I've moved to the project which is actively using CQRS + event sourcing. From the first glance it's implemented in accordance with all those books and blogs, but finally I realized what exactly is peevish in the implementation.
Here is CQRS architecture:
Originally I took this picture from here.
As we can see in the picture, the read side receives events from the queue and passes it one by one into different sets of projections(denormalizers) and then resulting ViewModels are saved through AddOrUpdate method into, say, DB. So as I understand from the picture denormalizer can rely only on the event itself plus data from read-side db. For instance:
Another case(counting number of some items, say orders):
What we have in our project: We use all those events only as a notifier that something changed in the domain model. Hence, what we do:
The approach we use in our project looks a bit strange to me, I can't see all the drawbacks of it though. If we need to rebuild our read side, we add "active" denormalizer and next time it receives a particular event, it recreates the new viewmodel.
If we use approach from the books, I will have to have a separate utils logic somewhere out of my system for rebuilding. What we need for this:
So my question is:
What is the right approach in here?
CQRS separates reads and writes into different models, using commands to update data, and queries to read data. Commands should be task-based, rather than data centric. ("Book hotel room", not "set ReservationStatus to Reserved").
CQRS is one of the important pattern when querying between microservices. We can use CQRS design pattern in order to avoid complex queries to get rid of inefficient joins. CQRS stands for Command and Query Responsibility Segregation. Basically this pattern separates read and update operations for a database.
Command query responsibility segregation (CQRS) is a programming design pattern that treats retrieving data and changing data differently. CQRS uses command handlers to simplify the query process and hide complex, multi-system changes.
The approach we use in our project looks a bit strange to me, I can't see all the drawbacks of it though.
One prominent drawback is that upon receipt of the event, you have to make an additional call to the repository of the corresponding aggregate. This means that this repository must be exposed, either directly or as a service. In addition to increased dependencies is the additional IO.
For rebuilding from an event store, the approach you describe is the generally accepted method. An approach described here makes use of an event log dedicated for rebuilding projections. This can be used to address performance issues while rebuilding. Also take a look at Scalable and Simple CQRS Views in the Cloud and on DDD/CQRS mailing list.
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