Defining the two event types
First, let's clarify the difference:
- Business Events describe an immutable fact that occurred at a specific moment in time. They are rich in business context and intent. For example, OrderApproved.
- State Events contain the full, current state of an entity after a change. They represent the "now" but often lack the context of why the state changed. For example, OrderUpserted.
The pitfalls of a pure approach
To make the distinction clear, consider the problems that arise when you rely exclusively on one type of event.
- The Pure Business Event Approach:
If your system only publishes business events, every consumer application that needs the current state of an entity is forced to do the heavy lifting. It must consume the entire history of events for that entity and reconstruct the state from scratch. This approach is highly inefficient, repetitive, and notoriously error-prone, as the same complex state-building logic is duplicated across many consumers.
- The Pure State Event Approach:
On the other hand, a system that only publishes state events is much simpler for consumers. They just take the latest event and have the full picture. However, this simplicity comes at a high cost: you lose the rich context of the business event. You know that something changed, but you don't know why. This makes it impossible for consumers to react to specific business moments, like an order being approved or shipped.
The solution: a "shift-left" pattern for state management
The most robust and scalable solution is to embrace both event types by implementing a "shift-left" pattern. This pattern moves the responsibility of state reconstruction from the many consumers (on the right) to the single data-owning producer (on the left).
In this model, the domain that owns the data—for example, the Order domain—is responsible for publishing:
- Business Events: To signal important business facts (OrderCreated, OrderApproved, OrderShipped).
- Aggregated State Events: To provide the complete, up-to-date state of the order.
- Specific Projections (Optional): To offer other tailored views or insights into an entity that may be useful for specific consumers.
This approach ensures that all complex business logic for state aggregation stays encapsulated within the owning domain, right where it belongs.
As a result, consumers have the flexibility to choose the event stream that best fits their needs. A consumer that needs to trigger an action based on a specific business moment (e.g., sending a shipping notification) subscribes to the business events. A consumer that simply needs the current state to display in a UI or populate a database subscribes directly and efficiently to the state event stream.
Conclusion: centralize logic, empower consumers
By placing the responsibility for state build-up on the producer side, you relieve every consumer from this complex task, leading to a dramatic improvement in data quality, consistency, and developer efficiency. This "shift-left" pattern is a cornerstone of a mature EDA, significantly increasing the scalability and maintainability of your entire ecosystem.
If you need expert guidance on how the "shift-left" pattern could transform your architecture, be sure to reach out.
