domain-driven-designcqrscommand-query-separationddd-service

Separate application service for command / query in CQRS implementation in Domain Driven Design?


When implementing CQRS with Domain Driven Design, we separate our command interface from our query interface.

My understanding is that at the domain level, this reduces complexity significantly (especially when using event sourcing) in the domain model since your read model will be different from your write model. So that looks like a separate domain service for your read-and-write bounded context.

At the application level, do we need a separate application service for the read and write separations of our domain?

I've been playing devil's advocate on the matter. My thoughts are it could be overkill, requiring clients to know the difference. But then I think about how a consuming web service might use it. Generally, it will issue requests for reading and post for writing, which means it already knows.

I see the benefits being cleaner application services.


Solution

  • The real value is having a properly separated read and domain model. They do fundamentally different things. And often have very different shapes. It's entirely possible for the read model to contain an amalgam of data from differing domain objects for example.

    When you think about how they are used and the way the function within an application you can start to appreciate the need for the separation. The classic example here is to consider the number of writes compared to the reads in a typical application. The reads massively outnumber the writes. By maintaining a difference you can optimise each side for it's respective role.

    Another aspect to bear in mind is that a 'post' will constitute a command not a viewmodel which may contain a read model. If using a CQRS approach you need to adapt the way you do queries and posts. In fact you can achieve a much more descriptive language rather than simply reflecting a view model back and forth to a server.

    If your interested I have a blog post which outlines the high level overview of a typical CQRS architecture. You can find it here: A step by step overview of a typical CQRS application. Hope you find it useful.

    Final point. We are in the process of adding new functionality and have found the separation to be very helpful. Changes to one side don't impact the other in the same way as they might.