Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CQRS Commands and Queries - Do they belong in the domain?

In CQRS, do they Commands and Queries belong in the Domain?

Do the Events also belong in the Domain?

If that is the case are the Command/Query Handlers just implementations in the infrastructure?

Right now I have it layed out like this:

Application.Common Application.Domain   - Model     - Aggregate   - Commands   - Queries Application.Infrastructure   - Command/Query Handlers   - ... Application.WebApi   - Controllers that utilize Commands and Queries 

Another question, where do you raise events from? The Command Handler or the Domain Aggregate?

like image 346
Sam Avatar asked Aug 26 '15 01:08

Sam


People also ask

Are queries part of the domain?

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.

Are read models part of the domain?

In event sourcing, read models do not represent domain entities by definition.

Should commands be immutable?

Commands are immutable because their expected usage is to be sent directly to the domain model side for processing. They do not need to change during their projected lifetime in traveling from client to server. Events are immutable because they represent domain actions that took place in the past.

What are commands in DDD?

Commands and events are both simple domain structures that contain solely data for reading. That means they contain no behaviour or business logic. A command is an object that is sent to the domain for a state change which is handled by a command handler.


2 Answers

Commands and Events can be of very different concerns. They can be technical concerns, integration concerns, domain concerns...

I assume that if you ask about domain, you're implementing a domain model (maybe even with Domain Driven Design).

If this is the case I'll try to give you a really simplified response, so you can have a starting point:

  • Command: is a business intention, something you want a system to do. Keep the definition of the commands in the domain. Technically it is just a pure DTO. The name of the command should always be imperative "PlaceOrder", "ApplyDiscount" One command is handled only by one command handler and it can be discarded if not valid (however you should make all the validation possible before sending the command to your domain so it cannot fail)
  • Event: this is something that has happened in the past. For the business it is the immutable fact that cannot be changed. Keep the definition of the domain event it in the domain. Technicaly it's also a DTO object. However the name of the event should always be in the past "OrderPlaced", "DiscountApplied". Events generally are pub/sub. One publisher many handlers.

If that is the case are the Command/Query Handlers just implementations in the infrastructure?

Command Handlers are semantically similar to the application service layer. Generally application service layer is responsible for orchestrating the domain. It's often build around business use cases like for example "Placing an Order". In those use cases invoke business logic (which should be always encapsulated in the domain) through aggregate roots, querying, etc. It's also a good place to handle cross cutting concerns like transactions, validation, security, etc.

However, application layer is not mandatory. It depends on the functional and technical requirements and the choices of architecture that has been made. Your layring seems correct. I would better keep command handlers at the boundary of the system. If there is not a proper application layer, a command handler can play a role of the use case orchestrator. If you place it in the Domain, you won't be able to handle cross cutting concerns very easily. It's a tradeoff. You should be aware of the pro and cons of your solution. It may work in one case and not in another.

As for the event handlers. I handle it generally in

  • Application layer if the event triggers modification of another Aggregate in the same bounded context or if the event trigger some infrastructure service.
  • Infrastructure layer if the event need to be split to multiple consumers or integrate other bounded context.

Anyway you should not blindly follow the rules. There are always tradeoffs and different approaches can be found.

Another question, where do you raise events from? The Command Handler or the Domain Aggregate?

I'm doing it from the domain aggregate root. Because the domain is responsible for raising events. As there is always a technical rule, that you should not publish events if there was a problem persisting the changes in the aggregate and vice-versa I took the approach used in Event Sourcing and that is pragmatic. My aggregate root has a collection of Unpublished events. In the implementation of my repository I would inspect the collection of Unpublished events and pass them to the middleware responsible for publishing events. It's easy to control that if there is an exception persisting an aggregate root, events are not published. Some says that it's not the responsibility of the repository, and I agree, but who cares. What's the choice. Having awkward code for event publishing that creeps into your domain with all the infrastructure concerns (transaction, exception handling, etc) or being pragmatic and handle all in the Infrastructure layer? I've done both and believe me, I prefer to be pragmatic.

To sum up, there is no a single way of doing things. Always know your business needs and technical requirements (scalability, performance, etc.). Than make your choices based on that. I've describe what generally I've done in the most of cases and that worked. It's just my opinion.

like image 189
Tomasz Jaskuλa Avatar answered Sep 20 '22 23:09

Tomasz Jaskuλa


In some implementations, Commands and handlers are in the Application layer. In others, they belong in the domain. I've often seen the former in OO systems, and the latter more in functional implementations, which is also what I do myself, but YMMV.

If by events you mean Domain Events, well... yes I recommend to define them in the Domain layer and emit them from domain objects. Domain events are an essential part of your ubiquitous language and will even be directly coined by domain experts if you practise Event Storming for instance, so it definitely makes sense to put them there.

What I think you should keep in mind though is that no rule about these technical details deserves to be set in stone. There are countless questions about DDD template projects and layering and code "topology" on SO, but frankly I don't think these issues are decisive in making a robust, performant and maintainable application, especially since they are so context dependent. You most likely won't organize the code for a trading system with millions of aggregate changes per minute in the same way that you would a blog publishing platform used by 50 people, even if both are designed with a DDD approach. Sometimes you have to try things for yourself based on your context and learn along the way.

like image 31
guillaume31 Avatar answered Sep 17 '22 23:09

guillaume31