I have a silly question from a new CQRS follower. Considering an
example UC to register a new customer in CRM system.
Customer has an address, which in turn has street, country, etc.,
customer has all sorts of names, contact information etc.
If the command is CreateNewCustomer, should the constructor of such
command accept all the atomic values for each of the attribute, or:
a) I should I create a separate command, like CreateNewCustomer,
ModifyCustomerAddress, ModifyCustomerEmployee, etc, and execute this
commands consequently from the UseCase.
b) Create a DTO, which will include references to ValueObjects from
the domain, and pass it to the constructor of the CreateNewCustomer
command? I suppose this might not be good practice, because DTO is
from the query model.
Any other best practices?
Thanks.
Long answer: maybe search this group's archive. IIRC, this question has
been discussed more than once in the not-too-distant past.
> b) Create a DTO, which will include references to ValueObjects from
> the domain, and pass it to the constructor of the CreateNewCustomer
> command? I suppose this might not be good practice, because DTO is
> from the query model.
You are right. DTOs from the query side and DTOs from the command side
(which are essentially *the commands*) never match in detail, not even
in a pure "update" scenario, which we all don't want to do anyways. The
reason is that on the query side you will always have additional data
for display purposes whereas the command side tends to be a lot of IDs
plus some entered data. Also, query side DTOs are only dumb data
containers whereas commands can very well contain validation and even
some preliminary authentication logic. Trying to combine both eventually
leads into a mess in my experience.
>
> Any other best practices?
Just a comment on vocabulary. "Value object" is a term from the domain
model. As such, a value object is first defined by its behaviour. In the
context of CQRS, by definition you cannot have a refence to a value
object in either queries or commands.
You can have a DTO that closely follows the internal state of a value
object. You can also have a part of a command that provides data
required in construction a value object within the domain. The first is
about behaviour, the latter about data (upon which the behaviour "behaves").
As always, just my 2 cts, Although I am beginning to feel quite strong
about these distinctions, so maybe I'll raise to 4 cts :)
Cheers
Phil
>
Ok, since my user intent is to register a new customer, and this is
also a single task from the user perspective, hence I have created a
single command - RegisterNewCustomer.
However, in order not to have any direct references to the domain, and
since the command is DTO, the command should cary all the attributes
of the customer entity and the related value objects, eventually
repeating them. It does not seem to be very good design. Did I missed
something?
Thanks.
Other tabs contains contact details, identification documents etc.
What is the "best practice" here?
Thanks.
> However, in order not to have any direct references to the domain, and
> since the command is DTO, the command should cary all the attributes
> of the customer entity and the related value objects, eventually
> repeating them. It does not seem to be very good design. Did I missed
> something?
No you didn't. I have come to accept this as a necessary side-effect of
cqrs+task-based ui. You will end up with partially similar - although
not identical - data structures in several places:
Viewmodels, commands, domain constituents, events, read models and query
results.
That per se is not bad design, rather the result of explicitly
decoupling the different models involved. The code you will need to
write connecting them is the explicit mapping between the different
models. CQRS doesn't come for free :)
Some people on this group endeavour to minimize this apparent overhead
by code generation off a meta model, but if you are just starting out, I
would recommend against that.
Tools like automapper can possibly reduce the required coding while
keeping flexibility and expressiveness.
Some of these data structures may even be eliminated by reuse:
- For entry forms, instead of repeating command parameters, I often use
live command objects as a property of an (input) viewmodel also
providing validation and basic authentication. This is actually a great
thing as my command DLLs are available on client and server side,
providing identical validation and authentication information.
- Query result and viewmodel: I design my query results such that they
can be directly bound to a view, so a viewmodel takes query result
objects as some properties. There is really no point in duplication here.
- Readmodel and query results may well be identical, too. But very often
I am doing some light joining with other BCs in the query, so my query
results tend to be richer than the individual readmodels. That's a
matter of taste, I suppose.
However, I maintain a strong separation between command parameters,
domain constituents (<- those are private implementation details of the
domain model anyways), event properties and readmodel data. In my
experience, coupling them leads to data-centric domains, which I try to
avoid.
BUT: if you find yourself having 100% correspondence on command
parameters -> domain objects -> readmodel, to me this is a very strong
indication that that particular business context shouldn't be using
cqrs+ddd in the first place. Check non-functional requirements to see if
you cannot get away with something simpler. Have a look at Udi Dahan's
video from DDDx 2011 at skillsmatter for some inspiration in this regard.
Regarding the tabbed wizard data entry, I see no problem in collection
data upfront and putting it in a single command. There was some
contribution by Udi Dahan some time ago towards that question, but I
confess I don't recall his bottom line right now. Maybe you can find it
in the archives.
Cheers
Phil
Instead of thinking on commands (man I hate that part of CQRS), I would first think of an Entity: CustomerRegistration.
And refactor as you get more information about correlated use cases.
Cheers,
Nuno
Instead of thinking on commands (man I hate that part of CQRS), I would first think of an Entity: CustomerRegistration.
And refactor as you get more information about correlated use cases.
Cheers,
Nuno
On Nov 21, 2011, at 8:29 PM, Philip Jander wrote:
I have seen Rinat's approach on binding several commands, related to
the same entity, into one CommandMessage. I think this should work
here as well?
Regards,
Veniamin
Batching commands in a single message is just a hack that allows you to avoid creating separate composite commands.Of course, your message dispatcher has to support transactional processing (either in form of ES or classical transactions) in order for this to work as expected (ie. if one of the commands fails - the entire batch fails)
?On Wed, Nov 23, 2011 at 6:16 PM, Rinat Abdullin <rinat.a...@gmail.com> wrote:
Batching commands in a single message is just a hack that allows you to avoid creating separate composite commands.Of course, your message dispatcher has to support transactional processing (either in form of ES or classical transactions) in order for this to work as expected (ie. if one of the commands fails - the entire batch fails)
Can of worms
I've been doing it in volatile cloud environments (which can be considered as parallel and concurrent, when you have multiple multithreaded VMs that come up and down according to the load). No problems with command batching and logical ES transactions whatsoever.Am I doing something wrong? :)
2011/11/23 √iktor Ҡlang <viktor...@gmail.com>:
--
Le doute n'est pas une condition agréable, mais la certitude est absurde.
Rinat
Yeah, forgot to mention that rule: only commands to the same entity are allowed to be batched. No crossing of the consistency boundaries with the transactional logic.
On Thu, Nov 24, 2011 at 4:28 AM, Rinat Abdullin
On Thu, Nov 24, 2011 at 4:38 AM, Rinat Abdullin
On Thu, Nov 24, 2011 at 4:42 AM, Rinat Abdullin
Daniel
--
♲ Made with 100 percent post-consumer electrons
Forgive the stupid question, but wouldn't it make more sense to send a
"batch" of commands at the transport layer,
Short term, my own understanding of why the experts make some of their
choices. It seems like treating batching as a transport layer
property would be a better model for a smart, disconnected client to
me, but Greg gives it as an example of where you can't avoid batching
at (what I read as) a higher level.
Longer term, we have clients in our system that currently receive a
batch of "commands", process them, generate a batch of results, and
ship that back as a report. We have a bunch of pressures to make them
less batch focused.
It seems like batching those responses at the "transport" level would
decouple more of our system from the details of the client, and the
fact that part of a service was operating in "disconnected" mode
compared to "connected" mode. (eg: explode the batch out, and now it
looks like a connected client to most of the system.)
Does that make sense?
Daniel
I have seen Rinat's approach on binding several commands, related to
the same entity, into one CommandMessage. I think this should work
here as well?
Also now that you don't necessarily need to use ES.
I've mentioned this several times. This similar to the ShoppingCart/PurchaseRegistration concept in relationship to a PurchaseOrder, PaymentOrder, ShippingOrder, other correlated long running business operations.
Each of these Aggregates can run on distinct Bounding Contexts but not necessarily.
Cheers,
Nuno
Sent from my iPhone