Skip to content

Instantly share code, notes, and snippets.

@beschauer
Last active May 2, 2017 20:23
Show Gist options
  • Save beschauer/d32faf54eec905c8aeb1ab977ae12f93 to your computer and use it in GitHub Desktop.
Save beschauer/d32faf54eec905c8aeb1ab977ae12f93 to your computer and use it in GitHub Desktop.
how to do projectsion in CQRS with event sourcing

= How to do projection in CQRS with event sourcing

http://stackoverflow.com/questions/4064067/event-sourcing-and-read-model-generation

  • Question regards just one field
  • chosen answer is pro, but comments with up votes are against

https://groups.google.com/forum/#!topic/dddcqrs/Xq1H2zJh3LU

  • If the data you need is already part of the Aggregate publishing the event it is trivial to put that data in the event.
  • If the Aggregate publishing the event does not contain the data then subscribe to events from multiple aggregates or bounded contexts
  • Examples where enriching events is a good idea:
    • An appointment is rescheduled from one schedule to another. The resulting event AppointmentRescheduledEvent contains both the schedule I rescheduled from and the schedule I rescheduled to. It makes it easier on my consumers (they don't have to figure out where it was rescheduled from by querying their own state (if they keep any state at all)). Because the appointment aggregate knew in which schedule it was before the reschedule command, it was very easy to enrich.
  • An end user fixes a typo in the name of a patient. The resulting event PatientNameTypoFixedEvent contains the fixed name. I can tell you that some of my event consumers are very much interested in this event (UI, HL7, reporting, services etc...) while others couldn't care less (slot search). Event conflict resolution does not allow two users to do this concurrently though (in the sense of optimistic concurrency - Gregory Young's second video).
  • Each time a command is executed on an appointment aggregate the resulting event contains a "soft" reference (an identifier of some sort) to the schedule, specialty, location, site, patient of the appointment. Do I reuse these when restoring appointment aggregate state? Depends on the type of event really. If an event "changed" one or more or the aforementioned attributes then yes, those are used to restore state. Do I find it confusing at times that there's no clear difference between what is innate to the event and what is enriched? Sometimes.
  • Anything to make that aggregate self-contained and be able to get it's job done during it's life-cycle. That could mean copying some state from another aggregate when it's constructed or altered. It could also mean that we should send a command to the aggregate to update some information inside of it. View(model)s on the other hand should just consume all necessary events and be able to figure out what to update. So product id and price at the time of order would probably be enough for the order aggregate (write side). If the order viewmodel (read side) wants to expand that product into many more attributes, then these could be copied over from another table in the read model (assuming relational here).
  • ... "what" to include in the events ... can only be answered by the domain experts. If the domain expert sais that the ProductDetailedDescription is an immutable part of the order line, then he is telling you that that information has to be part of the event. ... So there's your rule: include information in your event if the ubiquitous language tells you so. If the read model requires information the domain doesn't need? Well, the read model is part of the domain and the ubiquitous language, so if the read model needs it, include it.

https://www.lavinski.me/generating-read-models-with-event-sourcing/

  • Update! I've learnt a lot since writing this article and no longer recommend the conclusion I came to here. In short enriching events had unforeseen problems and I would instead recommend using only delta style events in a persisted event streams.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment