After module 4.3, the Kladde has modules per context, and in each module the rules sit in the domain model. So far everything is stored the same way: an aggregate is loaded, changed and written back into its table as the latest state. For quotes and appointments that is right. In this module one context gets a different form of data storage: sales, with its pipeline of sales opportunities (Deal). It no longer stores the latest state but everything that happened, and builds several views from it.

This first lesson doesn't write any code for the Kladde yet. It clarifies when this effort pays off and when it does harm, because both techniques are expensive and are often used where they bring nothing. At the end there is one decision per context, recorded as an ADR.

Two ideas that are often confused

CQS (Command Query Separation) is an old rule for methods that goes back to Bertrand Meyer: a method either changes something (a command) or answers a question (a query), but not both. quote.Send() changes and returns at most an error code; quote.Total answers and changes nothing. You have followed it since K1, often without knowing the name.

CQRS (Command Query Responsibility Segregation) lifts the same idea from the method to the model. There are two models:

  • the write model with the rules: the aggregate from module 4.3, which checks a command and accepts or rejects it;
  • one or more read models that exist only for display: a list with exactly the columns a page needs, a total per month, a search index. They have no rules and no methods that change anything.

Both models may live in the same database and even read from the same tables. CQRS doesn't mean “two databases” but “two models with two jobs”. The next lesson shows this light form with the contacts.

Event sourcing concerns something else, namely what is stored. Instead of the latest state, an aggregate stores the sequence of its events in the past tense: “deal opened”, “deal qualified”, “quote attached”, “deal won”. The state comes into being by applying the events one after the other. The events are the truth, the state is derived.

The two ideas relate like this:

  • CQRS works without event sourcing. That is the more common and cheaper case.
  • Event sourcing almost never gets by without CQRS. From a sequence of events it is hard to query a list like “all open deals worth more than 10,000, sorted by closing month”. For that you need read models that are built from the events. These building blocks are called projections (lesson 4.4.5).

The domain events from lesson 4.3.4 are related to the events here, but they are not the same thing. There the aggregate produced events to notify others; what was stored was still the state. In event sourcing the events are the storage.