Is there a rule of thumb where derived information goes?
As an example; suppose I have two integers 3 and 2, then I can derive information from it. The most obvious example is a sum. I figure a sum belongs in a projection.
But what if the derivation is a conclusion? Like 3 > 2 is an allowed state, it can occur in the normal usage, but something that the user needs to deal with before some deadline. So there is some kind of message “fix 3 > 2”. Does that belong in the projection or in the command model? This is less obvious to me, because it has a business rule aspect to it.
- sum = int1 + in2
- message = (int1 <= int2 ? “” : “fix it”)
What goes where?
You can store it in different places like you said… Command Model, Projection or even Events!
For me, it really depends on your domain and use case…
If this info, derived or not, is important and will be used on your Command Model (eg: business rules, validations, etc) → store in the Command Model
If this info is really really important for your business and you want to easily see it → store in the Events
If this info is only important for a specific user/client → store in the Projection
This would be more or less my rule of thumb for infos in general!
Just keep in mind the ‘migration path’ between them!
If you have it on a Command, it’s pretty easy to add it to your Command Model (Aggreate) later on
If you have it on an Event, it is pretty easy to add it to your Projections later on
Responding late, but this is a hobby project, other things took priority.
Thanks for pointing out that things can be stored in events as well, that is interesting indeed. I’m still struggling though. Let me provide a concrete situation in my trial project. It is about allocating people to shifts, possibly multiple shifts per date. A great use case to shake out all kind of frustrating issues.
If someone is allocated to a shift (AllocationSet), his/her day total changes. The allocation is in the command domain. The day total could also exist in the command domain, but since it is derived from the assignments it could also exist in a projection.
- Having an DayTotalChanged event stored in the event store feels incorrect, because it is derived.
- But using the AllocationChanged event causes issues, because the projection and the web layer both respond to this event asynchronously, and the projection may not have finished processing it.
- Putting the day total in the AllocationChanged event feels wrong as well, because there are other events that may cause the day total to change, like ShiftNumberOfHoursChanged.
It almost feels like the projection should also be able to send out events (DayTotalChanged) which do not get persisted. Like on the spring application event bus.