'Should the query side of a CQRS application call the database directly?
As title says:
Should the query side of CQRS applications call the database direcly in the controllers/handlers and skip application services, domains and repositories?
What if the query logic is complex and/or I also need to publish an event (related to the read operation) to a message broker? In what layer would that logic fit?
Solution 1:[1]
The Query side will only contain the methods for getting data, so it can/should be really simple. The domain model from the command side is definitely not part of the query side. The queries are separate from the model we have in our domain. An abstraction on top of your persistence is not required too.
Simple query logic would make your life easier. The secret sauce of CQRS is polyglot persistence. You may maintain multiple denormalized representations of your data, also known as a materialized views, which are tailored to your query needs.You can have multiple projections on your data on different databases depending on your query needs. If you do that, the query side tends to become simple e.g. if you have a projection of something that is an entity in your domain like a customer then you can persist it in Mongo and query it by id - really simple and performant, if you have some report with multiple orders you can persist those in a relational database and do sql queries - simple and performant. This way you would end up with GET queries that do database queries and return the read models without any additional mapping. Having said that, I would like to state that this a typical use case, but your read models can also be slightly different queries on the same table of a db. This would make the query a bit more complex, but might be good enough too.
I also don't think that you should publish an event from the query side. What would that event be?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
