Well, do command handlers return values or not?
They should not return Business Data, only meta data (regarding the success or failure of executing the command). CQRS
is CQS taken to a higher level. Even if you would break the purist's rules and return something, what would you return? In CQRS the command handler is a method of an application service
that loads the aggregate
then calls a method on the aggregate
then it persists the aggregate
. The intend of the command handler is to modify the aggregate
. You wouldn't know what to return that would be independent of the caller. Every command handler caller/client would want to know something else about the new state.
If the command execution is blocking (aka synchronous) then all you would need to know if whether the command executed successfully or not. Then, in a higher layer, you would query the exact thing that you need to know about the new application's state using a query-model that is best fitted to your needs.
Think otherwise, if you return something from a command handler you give it two responsibilities: 1. modify the aggregate state and 2. query some read-model.
Regarding command validation, there are at least two types of command validation:
- command sanity check, that verifies that a command has the correct data (i.e. an email address is valid); this is done before the command reaches the aggregate, in the command handler (the application service) or in the command constructor;
- domain invariants check, that is performed inside the aggregate, after the command reaches the aggregate (after a method is called on the aggregate) and it checks that the aggregate can mutate to the new state.
However, if we go some level up, in the Presentation layer
(i.e. a REST
endpoint), the client of the Application layer
, we could return anything and we wont' break the rules because the endpoints are designed after the use cases, you know exactly what you want to return after a command is executed, in every use case.