Event Sourcing Principles
Event sourcing is a pattern where state changes are stored as a sequence of immutable events, rather than maintaining only the current state.
What is Event Sourcing?
In traditional systems, we store the current state of entities in a database. When something changes, we update that state, losing the history of how we got there. Event sourcing takes a different approach: instead of storing just the current state, we store a sequence of events that led to that state.
Think of it like a bank account statement. Instead of just showing your current balance, the statement lists every transaction (deposit, withdrawal) that affected your balance. Your current balance is derived by replaying all those transactions in order.
Key Concepts
Events as First-Class Citizens
Events represent facts that have happened in the past. They are immutable - once an event has occurred, it cannot be changed or deleted. Events have a timestamp and carry data about what happened.
Immutable Event Logs
Events are stored in an append-only log. New events are added to the end, but existing events are never modified. This provides a complete audit trail of everything that has happened in your system.
State Reconstruction
The current state of any entity can be reconstructed by replaying all its events from the beginning. This is like "replaying history" to see how we arrived at the current situation.
Time Travel Debugging
Because we have a complete history, we can reconstruct the state at any point in time. This is invaluable for debugging issues: "What did the order look like when the customer submitted it?"
In This Workshop
We use event sourcing for purchase orders in our e-commerce system. Each order goes through a series of state transitions:
CREATED → PENDING → COMPLETED
↓
SHIPPED → DELIVERED
↓
CANCELLED
Each state transition is represented by an event. The PurchaseOrderStatus enum in our spring-boot-kafka-common module defines these states:
public enum PurchaseOrderStatus {
CREATED, // Order received
PENDING, // Order being processed
COMPLETED, // Order fulfilled
CANCELLED, // Order cancelled
SHIPPED, // Order dispatched
DELIVERED // Order completed
}
When a customer submits an order, we create a PurchaseOrderDTO event with status CREATED and publish it to the purchase-orders Kafka topic. The backend consumer processes this event and updates the order state accordingly.
Benefits of Event Sourcing
- Complete Audit Trail: Every change is recorded with timestamp and details
- Debugging Capabilities: Reconstruct past states to understand what happened
- Temporal Queries: Answer questions like "What was the order status at 3pm yesterday?"
- Event Replay: Fix bugs by replaying events with corrected logic
- Multiple Projections: Create different views of the same data for different use cases
Challenges
- Event Schema Evolution: As your system evolves, event formats must remain backward compatible
- Storage Growth: Event logs grow continuously and need proper retention policies
- Complexity: More moving parts compared to traditional CRUD systems
- Eventual Consistency: State updates are asynchronous, requiring careful handling
Key Takeaways
- Events are immutable facts that have happened in the system
- Current state is derived by replaying all events in sequence
- Enables complete audit trails and time-travel debugging capabilities
- Schema evolution and storage growth require careful planning