0

I would like to ask what is the preferred way of passing additional state to projections.
I have UserAggregate that is watching changes of several attributes of user (for instance address, name and state).

I have to read a model or projection that need all user attributes on any change.
Is it better to just write all attributes to every user event (so projection can be stateless), or for projection to keep state per user (so events can be more slim), or is there another way of doing such thing?
In case of every attribute in event, does it make sense to just store state of aggregate in every event?

For instance if my user also has an attribute age, that maybe I will need in the future in this projection, it would be hard to rerun all events, since age is absent in older events ...

0

In Event Sourcing:

  • A Projection is the State of the System at some point in time.
  • An Event is the change that occurred to the "State of the System" at some point in time.

Regardless of how you cut it the state enters the system as an event, and is aggregated into a projection in order to facilitate processing.

So the questions are:

  • Do I need age in order to accomplish the work? Yes, then it needs to be persisted/added to the appropriate projection and the events that source it
  • Do I need age in order to accomplish a non-functional goal (such as recording it to settle legal requests)? Yes, then it needs to be persisted/added to the appropriate projection and the events that source it

Otherwise why do you have an event carrying age? It should be eliminated as it is unnecessary overhead.


I am confused by why you seem to also be passing a user object along for the ride. This runs counter to the idea that all of the data is in the event stream, and will break your architecture.

I would refactor that dependency out. Ensure that the projections can handle this data, and issue a one time batch of events giving the appropriate properties to every current user. Perhaps issue events to mark non-current users as dead. This will push your code back toward the architecture, making it less confusing.

Alternately, stop considering this as an event sourcing system. The Projection becomes a request object, events are the problem of whomever assembles the request. Now it follows Command Query architecture and the reasonable answer is that user properties are on user. Failure to provide them will fail the request.

| improve this answer | |
  • Maybe i don't understand clearly, I was considered that aggregates should hold the state and issue events for projections to project them to the real world, so, was I wrong? Since then I hit this problem aggain when I start creating email sending projection... The projection becomes a request object and following. Do I understand it that I probably should put aggregate in front of that projection (throught project manager) that would generate event specialized for that projection with all data that it need? Because that is how I'm planning to solve problem with emails – mct Nov 15 '19 at 8:27
  • Your reasoning is sound. My point is that projections are just a data, while aggregates are domain objects. You can make a domain object based off a projection, or even have the domain object hold several projections. You should never give the projection itself domain knowledge, hence the projection itself cannot generate events, or perform functions beyond composing itself from the event stream or allowing a viewer to read the data. – Kain0_0 Nov 17 '19 at 23:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.