user1016265
user1016265

Reputation: 2397

updating query part in CQRS

I've read a lot of articles about CQRS, and one small thing I still can't understand. Everywhere written that there are two models (they might have two different type of data storages even). Where is one model is called write model and another one is read.

Here is the flow: for instance, write model makes some changes, store those changes into (own) DB, and fire an event. Then read model, which has to be subscribed on such event, handle it and update own projection is this correct? If yes then it means basically that something what people call read model is not reading only from the storage.

What I'm missing? The main question is what the part is responsible for updating projections/query part?

P.S. Thanks guys for your replies! Now puzzle is assembled :-)

Upvotes: 4

Views: 2884

Answers (2)

VoiceOfUnreason
VoiceOfUnreason

Reputation: 57367

If yes then it means basically what people call read model which not reading only.

Mostly correct.

Your entities in the write model have a public interface that contains the write methods, but they also include a restricted interface that copies the current state (a read). Your entities in the read model have a public interface that contains read methods, but also include a restricted interface that replaces the current state (a write).

There's a process in the middle that uses the restricted interface to read the state of the write model, transforms it from the write-optimized data structure to the read optimized data structure, and then uses the restricted interface to write this new state to the read model.

I think it is useful to introduce the concept of a store, that is distinct from the model. The write model makes changes to the write store (aka the book of record), and the read model uses the state published by the read store to answer queries, and the restricted interfaces are used to link the two stores; this creates the bridge between the write model and the read model.

Store in this case might just be in memory; in java, for instance, you might update the read store by updating a volatile handle to a read optimized data structure. The methods in the data model just grab the most recently available version of the data structure, and keep using that copy until the query is finished (ensuring that the read model produces a query result that is internally consistent).

You generally want the process in the middle to be decoupled from the updates to the write model itself. It might be event driven (when we see a domain event, build a new copy of the read optimized data structures changed by that event, and publish them). It might be scheduled (every so often, query the book of record for domain events, and process the ones that we haven't seen yet). The events themselves might contain all the state needed to rebuild the read structures (this is likely if you are using event sourcing in the write model), or it may be that the events simply identify the aggregates that have changed, and the process needs to query the book of record to find all of the relevant state.

Lots of choices, but they tend to follow the same basic pattern.

Upvotes: 1

tomliversidge
tomliversidge

Reputation: 2369

The way I understand it...

The write/command side is the domain model with the responsibility of making sure the system is in the correct state - if using DDD then through aggregates. You load your aggregate and apply some behaviour. This is the point where your business rules and behaviour live. This is also where you would raise domain events. This is a good way to do it (especially combined with event sourcing where your database is your events). However, I don't believe CQRS mandates using events. You could, for example, just update some state in a sql database. The command side is for protecting the invariants of your domain,

Then read model, which has to be subscribed on such event, handle it and update own projection is this correct?

If you're using events, yes. But also, see below...

If yes then it means basically that something what people call read model is not reading only from the storage.

It depends on your storage and how you are "creating" your read models. You could subscribe to events, then update read models in some database (could be tables in a SQL database, documents in a document database), or in an in-memory object model. You would then query these read models by loading them from the database or the in-memory model.

However, you can also have CQRS without events. In this scenario, the concept of a read model might just be a database query. i.e. a SQL query. that reads from the same storage as your write side.

For example, an API or web page request comes in, you execute a query against your database, then return the results to the user. This query doesn't go through the domain model. You have still separated your reads from your writes, you just haven't used events.

The main question is what the part is responsible for updating projections/query part?

If you're using events, it will be the subscribers to the events. You would listen to events, then update your read models. The actual implementation of these would depend on your architecture. For example, if using EventStore the client has built in support for the concept of subscribers. These could be implemented in a simple console app for example, or inside an API.

The flow for this might go like:

  • App starts
  • Subscribe to N streams of events
  • When you receive an event, update a database, or an in-memory model

If you're not using events then it's different. Your architecture might be simple enough that the read side just queries the db (that is already up-to-date from the command side!).

Upvotes: 4

Related Questions