We are trying out CQRS. We have a validation situation where a CustomerService (domain service) needs to know whether or not a Customer exists. Customers are unique by their email address. Our Customer repository (a generic repository) only has Get(id) and Add(customer). How should the CustomerService find out if the Customer exists?
CQRS commands and the onion architectureCommands belong to the core domain (just like domain events). They play an important role in the CQRS architecture - they explicitly represent what the clients can do with the application.
CQRS is a popular architecture pattern because it addresses a common problem to most enterprise applications. Separating write behavior from read behavior, which the essence of the CQRS architectural pattern, provides stability and scalability to enterprise applications while also improving overall performance.
Queries used by the UI can be part of the UI and so on. The point of CQRS is to have at least 2 models and the Command should be the domain model itself. However you can have a Query model, specialised for domain usage but it's still a read (simplified) model.
It's always in-sync. CQRS is rarely synchronous because we want to work/scale with different resources, type of databases, use a messaging infrastructure: we can rarely make a distributed transaction cross-resources (we could talk about XA or Sagas but… not now!).
Take a look at this blog post: Set based validation in the CQRS Architecture.
It addresses this very issue. It's a complex issue to deal with in CQRS. What Bjarte is suggesting is to query the reporting database for existing Customer e-mail addresses and issue a Compensating Command (such as CustomerEmailAddressIsNotUniqueCompensatingCommand
) back to the Domain Model if an e-mail address was found. You can then fire off appropriate events, which may include an UndoCustomerCreationEvent
.
Read through the comments on the above blog post for alternative ideas.
Adam D. suggests in a comment that validation is a domain concern. As a result, you can store ReservedEmailAddresses in a service that facilitates customer creation and is hydrated by events in your event store.
I'm not sure there's an easy solution to this problem that feels completely clean. Let me know what you come up with!
Good luck!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With