0

After reading dozens of articles and watching hours of videos, I don't seem to get an answer to a simple question:
Should static data be included in the events of the write/read models?

Let's take the oh-so-common "orders" example.
In all examples you'll likely see something like:

class OrderCreated(Event):
    ....

class LineAdded(Event):
    itemID
    itemCount
    itemPrice

But in practice, you will also have lots of "static" data (products, locations, categories, vendors, etc).
For example, we have a STATIC products table, with their SKUs, description, etc. But in all examples, the STATIC data is never part of the event.

What I don't understand is this:

  1. Command side: should the STATIC data be included in the event? If so, which data? Should the entire "product" record be included? But a product also has a category and a vendor. Should their data be in the event as well?
  2. Query side: should the STATIC data be included in the model/view? Or can/should it be JOINED with the static table when an actual query is executed.
  3. If static data is NOT part of the event, then the projector cannot add it to the read model, which implies that the query MUST use joins.
  4. If static data IS part of the event, then let's say we change something in the products table (e.g. typo in the item description), this change will not be reflected in the read model.

So, what's the right approach to using static data with ES/CQRS?

user1102018
  • 4,369
  • 6
  • 26
  • 33

1 Answers1

1

Should static data be included in the events of the write/read models?

"It depends".


First thing to note is that ES/CQRS are a distraction from this question.

CQRS is simply the creation of two objects where there was previously only one. -- Greg Young

In other words, CQRS is a response to the idea that we want to make different trade offs when reading information out of a system than when writing information into the system.

Similarly, ES just means that the data model should be an append only sequence of immutable documents that describe changes of information.

Storing snapshots of your domain entities (be that a single document in a document store, or rows in a relational database, or whatever) has to solve the same problems with "static" data.


For data that is truly immutable (the ratio of a circle's circumference and diameter is the same today as it was a billion years ago), pretty much anything works.

When you are dealing with information that changes over time, you need to be aware of the fact that that the answer changes depending on when you ask it.

Consider:

Monday: we accept an order from a customer
Tuesday: we update the prices in the product catalog
Wednesday: we invoice the customer
Thursday: we update the prices in the product catalog
Friday: we print a report for this order

What price should appear in the report? Does the answer change if the revised prices went down rather than up?

Recommended reading: Helland 2015

Roughly, if you are going to need now's information later, then you need to either (a) write the information down now or (b) write down the information you'll need later to look up now's information (ex: id + timestamp).

Furthermore, in a distributed system, you'll need to think about the implications when part of the system is unavailable (ex: what happens if we are trying to invoice, but the product catalog is unavailable? can we cache the data ahead of time?)

Sometimes, this sort of thing can turn into a complete tangle until you discover that you are missing some domain concept (the invoice depends on a price from a quote, not the catalog price) or that you have your service boundaries drawn incorrectly (Udi Dahan talks about this often).


So the "easy" part of the answer is that you should expect time to be a concept you model in your solution. After that, it gets context sensitive very quickly, and discovering the "right" answer may involve investigating subtle questions.

VoiceOfUnreason
  • 52,766
  • 5
  • 49
  • 91