Search code examples
domain-driven-designevent-sourcing

Events only for updating projection


We're introducing event sourcing and refactoring to a rich domain model in a part of our application and we're a little bit confused about a part.

We have Tanks, which are the aggregate root and we receive TankGauge information on those Thanks every so often. Since the historical gauging information is not relevant for any business logic, the aggregate doesn't hold a collection of all the gauges, it only has a reference to the most recent gauge.

To display the historical gauges, we do have a projection set up.

Now we're getting the request: we want to update remarks on a historical gauge. The only relevancy this has is on the projection that holds the historical gauges. This causes a situation in which applying the RemarkSetOnHistoricalGauge event on the aggregate is basically a no-op and only the projection will be updated accordingly.

This works but it feels counter a bit counter-intuitive. Any suggestions on this approach?


Solution

  • I would consider whether you have two bounded contexts here:

    • the tank gauging context: consuming TankGauge commands, validating that they make sense (if you're not, then there's not really a point to having the Tank aggregate) and emitting a TankGaugeWas (TankLevelWas?) event
    • the tank history context: allowing remarks/annotations to be made regarding historical levels

    Both of these have a concept of a tank, but not the same one. The history context consumes events from the gauging context (those events become commands, implicitly "incorporate this event into your worldview", from the perspective of the history context). They can have different aggregate logic: it might even be worth modeling a tank history aggregate as being time-windowed, e.g. that the tank tomorrow is not the same aggregate as the same tank today (this has the main benefit that you don't have to load the entire history of measures or scan through a history of snapshots).

    This ability to actually cover the situation where different contexts are using a term to mean different things is one of the strengths of DDD (and the fact that the term takes on a different meaning is a very strong sign that there's a context boundary being crossed).