Command Validation in DDD with CQRS

chris picture chris · Aug 27, 2015 · Viewed 8.3k times · Source

I am learning DDD and making use of the CQRS pattern. I don't understand how to validate business rules in a command handler without reading from the data store.

For example, Chris wants to give Ashley a gift.

The command might be GiveGiftCommand.

At what point would I verify Chris actually owns the gift he wants to give? And how would I do that without reading from the database?

Answer

Tomasz Jaskuλa picture Tomasz Jaskuλa · Aug 27, 2015

There are different views and opinions about validation in command handlers.

Command can be rejected, we can say No to the command if it is not valid.

Typically you would have a validation that occurs on the UI and that might be duplicated inside the command handler (some people tend to put it in the domain too). Command handler then can run simple validation that can occur outside of the entity like is data in correct format, are there expected values, etc.

Business logic, on the other hand, should not be in a command handler. It should be in your domain.

So I think that the underlying question is...

Should I query the read side from Command Handlers?

I would say no. Do not use the read model in the command handlers or domain logic. But you can always query your read model from the client to fetch the data you need in for your command and to validate the command. You would query the read side on the client to check would if Chris actually owns the gift he wants to give. Of course, the validation involving a read model is likely to be eventually consistent, which is of course another reason a command could be rejected from the aggregate, inside the command handler.

Some people disagree saying that if you require your commands to contain the data the handler needs to validate your command, than you can never change the validation logic within your handler/domain without affecting the client as well. This exposes too much of the domain knowledge to the client and go against the fact that the client only wants to express an intent. So they would tend to provide an GiftService interface (which are part of the ubiquitous language) to your command handler and then implement the interface as needed - which might include querying the read side.

I think that the client should always assume that the commands it issues will succeed. Calling the read side to validate the command shouldn't be needed. Getting two contradictory commands is very unlikely (users creating accounts with the same email address). Then you should have a mean to issue a corrective action, something like for example a Saga/Process Manager. So instead making a corrective action would be less problematic that if the command could have been validated and not dispatched in the first place.