4 ms·
You are quite right, event sourcing on its own is not great for read, and the "re-compute everything" (aka foldl) is problematic. CQRS solves this by producing
by yrashk 10y ago
You are quite right, event sourcing on its own is not great for read, and the "re-compute everything" (aka foldl) is problematic. CQRS solves this by producing a read-side that aggregates events into your domain. Classic event sourcing also attempts to solve the re-computation problem by snapshotting.
It is great that you mention that 90% of the time you want "the last version". That was one of my discoveries with event sourcing as well.
So what I came to is that re-computation (foldl) is a nice generalization, but isn't very practical. Instead, index the events and build the state on demand by querying the indices. This way, [plurality enabling] domain modelling moves to the code (as opposed to the database) and allows for quick changes in how you see the information.
You can read more about it at https://blog.eventsourcing.com/why-use-eventsourcing-database-6b5e2ac61848#.o1q5yb3p9 https://blog.eventsourcing.com/why-use-eventsourcing-databas... and https://blog.eventsourcing.com/lazy-event-sourcing-ed7e59007e17#.v5fa8aqbt https://blog.eventsourcing.com/lazy-event-sourcing-ed7e59007... as well as other articles on that blog.
- mamcx 10y agoThe cognitive struggle I have is how not only 90% on reads I need the last version, but also on write. The classical example is how avoid duplicated data or do validation across tables. One of the requirements of my app is deny a sale if the customer have pending invoices. The tricky part with invoice is that entry must be fast (I'm competing against DOS apps that fly at data-entry). So when ES say "Record the event, then build the read side at later time", instead me (and I think, many of us) wanna the opposite "Put into the event log after we have do validations". Of course, some actions can be delayed, but some need be as-now. How do this elegantly? My initial attempt is code against the tables and use triggers for recording the story, but that is not as nice...
- yrashk 10y agoThis is actually how I do event sourcing in many ways. The entry happens through commands, which can do validations prior to emitting a stream of events to be journaled. I also expose a locking mechanism to commands so that they can ensure the uniqueness or property validations are correct. In lazy event sourcing, you don't "build the read side at a later time", it's built upon receipt — in a form of indices, as they are THE read side and you pull this data and form domain objects on demand (by querying your indices), just transforming one representation (relevant events) into another (domain objects). Does this help?
- mamcx 10y agoHow you "expose a locking mechanism to commands"? And how you build the indices?