# Kevin Hoffman - Real-World Event Sourcing (Highlights)

## Metadata
**Review**:: [readwise.io](https://readwise.io/bookreview/50183777)
**Source**:: #from/readwise #from/zotero
**Zettel**:: #zettel/fleeting
**Status**:: #x
**Authors**:: [[Kevin Hoffman]]
**Full Title**:: Real-World Event Sourcing
**Category**:: #books #readwise/books
**Category Icon**:: 📚
**Highlighted**:: [[2025-04-02]]
**Created**:: [[2025-04-12]]
## Highlights
- The fundamental idea of Event Sourcing is that of ensuring every change to the state of an application is captured in an event object, and that these event objects are themselves stored in the sequence they were applied for the same lifetime as the application state itself. ([Page 2](zotero://open-pdf/library/items/RTS6RS3S?page=18&annotation=MIRVI7IB)) ^871601171
- Eventually, working by splitting commands, events, and state becomes second nature. ([Page 7](zotero://open-pdf/library/items/RTS6RS3S?page=23&annotation=ATQ8BVFV)) ^871601172
#keypoint
- As you’ll see in a bit, the command handler needs the state to validate the command, while the event handler needs the state to produce new state. ([Page 7](zotero://open-pdf/library/items/RTS6RS3S?page=23&annotation=XM3GSJ8K)) ^871601173
- Put another way, a command represents a request for something to happen, an event represents what actually happened, and the two will only ever look identical in the simplest of cases. ([Page 9](zotero://open-pdf/library/items/RTS6RS3S?page=25&annotation=RJ3K4D2L)) ^871601174
- All Events Are Immutable and Past Tense. ([Page 10](zotero://open-pdf/library/items/RTS6RS3S?page=26&annotation=LYPAUT46)) ^871601175
#favorite #law
- Modeling the absence of a thing or a thing that didn’t actually occur may often seem like a good idea, but doing so can confuse both developers and event processors. Remember that if an error didn’t result in some immutable thing happening, it shouldn’t be modeled as an event. ([Page 10](zotero://open-pdf/library/items/RTS6RS3S?page=26&annotation=XYU368NB)) ^871601176
- Applying a Failure Event Must Always Return the Previous State. ([Page 11](zotero://open-pdf/library/items/RTS6RS3S?page=27&annotation=7I5FSB5W)) ^871601177
#law
- As you’ll learn in this book, aggregate state is not to be shared and not meant for external consumption. In the next chapter, you’ll learn about a special kind of state optimized for external consumption called the projection. ([Page 12](zotero://open-pdf/library/items/RTS6RS3S?page=28&annotation=5UNL6B5B)) ^871601178
- Application of events and commands is pure and referentially transparent ([Page 12](zotero://open-pdf/library/items/RTS6RS3S?page=28&annotation=5YAV8BF5)) ^871601179
- By pure, we mean that the function can have no side effects. ([Page 13](zotero://open-pdf/library/items/RTS6RS3S?page=29&annotation=WDYNEYD9)) ^871601180
- You can design your read model so that the data required to answer any query is pregenerated, anxiously awaiting an incoming query. ([Page 16](zotero://open-pdf/library/items/RTS6RS3S?page=31&annotation=HHRPSBD7)) ^871601181
- In more formal terms, you’ll build a projector that takes data from events in the event log and stores that data in a read model projection, which can then be queried by consumers. ([Page 16](zotero://open-pdf/library/items/RTS6RS3S?page=31&annotation=CGH4JCHI)) ^871601182
- All Data Required for a Projection Must Be on the Events. ([Page 17](zotero://open-pdf/library/items/RTS6RS3S?page=32&annotation=L29G9WPL)) ^871601183
#law
- Using the injector and notifier patterns lets us manage side effects without affecting the pure functional nature of the rest of the system. ([Page 27](zotero://open-pdf/library/items/RTS6RS3S?page=41&annotation=8M9X7UVI)) ^871601184
- GenStage ([Page 33](zotero://open-pdf/library/items/RTS6RS3S?page=47&annotation=VEQ98LIX)) ^871601185
Equivalent in Ractor: OutputPort
- Work Is a Side Effect. ([Page 48](zotero://open-pdf/library/items/RTS6RS3S?page=62&annotation=5C2E6KPI)) ^871601186
#law
- The core primitives of aggregates, projectors, and process managers must never do work. ([Page 49](zotero://open-pdf/library/items/RTS6RS3S?page=63&annotation=AU5ZWAJ6)) ^871601187
- All Projections Must Stem from Events. ([Page 52](zotero://open-pdf/library/items/RTS6RS3S?page=66&annotation=8XEQLYHY)) ^871601188
#law
- Never Manage More than One Flow per Process Manager. ([Page 52](zotero://open-pdf/library/items/RTS6RS3S?page=66&annotation=FCSCRZMQ)) ^871601189
#law
- process managers must never emit events ([Page 65](zotero://open-pdf/library/items/RTS6RS3S?page=79&annotation=Y8CVTGSX)) ^871601190
- An event handler that emits commands but is not a process manager is a specialized form of gateway that we’ll refer to as a multiplexer. ([Page 73](zotero://open-pdf/library/items/RTS6RS3S?page=87&annotation=7JH8MXQK)) ^871601191
- The important tip to take away from this section is that you should choose how you persist data separately for each of the three different data types in an event-sourced system. ([Page 78](zotero://open-pdf/library/items/RTS6RS3S?page=92&annotation=4TZ2DCAB)) ^871601192
- Process Managers Must Not Read from Projections. ([Page 90](zotero://open-pdf/library/items/RTS6RS3S?page=104&annotation=ACUIUC5A)) ^871601193
#law
- It can be tempting to just query from a projection in order for a process manager to gather the information it needs to do its job. This is a dangerous temptation that needs to be resisted. ([Page 90](zotero://open-pdf/library/items/RTS6RS3S?page=104&annotation=PFNERRG2)) ^871601194
- active_construction_sites ([Page 91](zotero://open-pdf/library/items/RTS6RS3S?page=105&annotation=4GWP9VA8)) ^871601195
The process manager generates the projection by itself.
- The most important thing to notice here is that the list of active construction sites is now being monitored by the internal state of this process manager. ([Page 93](zotero://open-pdf/library/items/RTS6RS3S?page=107&annotation=LTEY52LT)) ^871601196