DDD/CQRS Querying Events
Asked Answered
A

3

6

I was looking at post's on querying in application designed with approach Event Sourcing/DDD/CQRS.

As I understand events are changes to the state of a domain object. The changes to state will be maintained as history/events in DB(any of sql/no sql).

If user wants to query to get current state for a particular aggregate root, it will involve fetching history of events.

When user will query especially business specific queries he/she will be interested in current state not the history of events.

How querying or 'Q' part in CQRS works with event sourcing?

Consider I have a domain object "Account" as aggregate root. The account AR will go through lots of changes i.e. credits debits. event store will have credit and debit events.

Consider user is required to get current balance of an account, how stream of history of events will suite here? How will user fetch current balance for given account?

I am unable to understand, How for business specific querying history of events will be useful?

-Prakhyat M M

Ascogonium answered 28/8, 2014 at 7:23 Comment(0)
I
6

I would recommend you to read more articles from Greg Young (He is like the father of CQRS and Event Sourcing), like this: CQRS, Task Based UIs, Event Sourcing... agh.

Sorry for my bad English, I am from Paraguay. But I really like DDD - CQRS - ES and I would like to try to make a point.

The use of "Projections" (also known as Materialized Views) and the concept of "Eventual Consistency" are the fundamentals that every practitioner of CQRS should understand very well. The Event Store is for query. Is in the Command side of CQRS, not the in the Query side. You may use a bus to send the events stored in the Event Store to the query side in order to process and generate a read model, or view models, from which you can query. In any case a eventstore per se is a query model.

Looks like you are a Java guy, but, still, you may want to check the CQRS Journey from Microsoft. Hope this helps a little bit and motivates you to do more research on DDD / CQRS / ES, the New Trio of Line of Business Applications.

Iridis answered 29/12, 2014 at 13:21 Comment(0)
K
5

You'll use a projection of the event stream into the read model, that contains exactly those information that the Query-side (Q) needs. For example, you could have an "account balance" projection that follows all events that change the account balance, but possibly ignores other events in the account's stream (such as owner changes). The projection then saves that info in a way that it can be queried very quickly, e.g., in memory or in a small read-model database table (accountId, balance) with the accountId as the key (database can be a key-value store, for example).

I suggest further reading on the CQRS concept such as this one or this one.

Kop answered 28/8, 2014 at 9:40 Comment(10)
Alexander, thanks for the reply. I got the missing context. Projections are really efficient.Ascogonium
Alexander, I am using akka persistence for my app. I have taken DDD/CQRS approach. I have no issues in write side. Feel I dont have enough understanding in building query side. What will be the case when querying requires data from multiple aggregate roots?Ascogonium
Sorry, I have no experience with akka persistence; your projections can listen to multiple aggregate roots (even of different type) of course.Kop
Alexander, thanks again. I am changing context of my question. If you want i can create separate post for it. But I cant stop myself from asking you, How do you handle a case where one command has to update state of two different aggregate roots. Command has to update both the AR's or none. To be clear how to handle transaction updates involving multiple aggregate roots?Ascogonium
The general rule is to avoid this situation. Please read some of the rich literature on that topic, there's plenty, e.g., the "Effective Aggregate Design" series by Vaughn Vernon (dddcommunity.org/library/vernon_2011) or informit.com/articles/article.aspx?p=2020371&seqNum=5Kop
Do you want banking type of project using DDD ?Zoellick
I am looking at applications architected with ddd/cqrs approach. For this approach my design involves akka persistence. Akka persistence is solving my write side but not the querying part and also inter domain object updates in one transaction. As Alexander mentioned we need to avoid one update involving multiple aggregate roots. I understand by proper ddd and bounded context definition there will be no scope for transaction. Still business use cases will lead to one command multiple aggregate root changes. What is the solution.Ascogonium
This is answered in the third question here.Kop
Alexander, don't you think so projections will lead to duplicate data. App will maintain domain state and projections will have its own data for specific querying. Correct me if I am wrong.Ascogonium
Yes, this is the very idea of CQRS+ES. If your use-cases are such that you'll always simply return the (complete) state of aggregates and will never span, for example, multiple aggregates, then, yes, that means duplicate data. In that case, you might be better go for a CRUD architecture.Kop
D
5

Interesting enough, recently more people discover using event store as the read model, leaving projections and "proper" read models until absolutely necessary.

We all know that dealing with projections increases the complexity. At minimum you have to create new models, establish the DAL for the read model and create projections to translate event to the read model changes, and bind those projections to the stream of events from your store. It requires more code, more moving parts and some of them are not easy to test. Schema changes at the read side also require migrations.

It appears that for many scenarios reading all events (properly partitioned) might be enough to have your "read model". It takes not much time until the system really grows large so you need to read tens of thousands of events to create one UI screen. But before you reach this point, you can just read events. May be use the file system to store events although tools like EventStore are free and quite easy to use. May be add some indexing.

This approach let you stabilise the domain significantly, you get more knowledge about how the system works, tune the events and be really prepared to bring the "proper" read model into the system, but you might not have to.

Adam Dymitruk has wrote a blog post about it, you might find it worth reading even if you don't want to take this approach. Greg Young also gave a talk EventStore as read model back in 2012.

Distended answered 22/1, 2017 at 14:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.