Event Sourcing Pattern
Contents
Event Sourcing Pattern
It stores all changes to application state as a sequence of events rather than only saving the current state. This enables reconstruction of past states and provides a reliable audit trail.
- Supports full history tracking and auditing, useful for compliance and debugging.
- Ideal for financial systems where transactions and account histories must be reconstructed accurately.
Key concepts:
- The Aggregate Root: In microservices, the “Aggregate” is the consistency boundary. For an Order service, the Order Aggregate ensures that you don’t “Ship” an order before it is “Paid.” It replays past events to calculate its current state before deciding if a new command is valid.
- Snapshotting: If an aggregate has 10,000 events, replaying them all is slow. A Snapshot saves the state at event #10,000. The system loads the snapshot and only replays events that happened after it.
- Event Versioning: In a long-running system, your event schema will change (e.g., adding a
zipCodeto anAddressUpdatedevent). You must handle Upcasting i.e. transforming old event formats into new ones during replay.
Java example using Axon:
@Aggregate
public class AccountAggregate {
@AggregateIdentifier
private String accountId;
private double balance;
// Command Handler: Logic to validate and create event
@CommandHandler
public AccountAggregate(CreateAccountCommand cmd) {
apply(new AccountCreatedEvent(cmd.getId(), cmd.getInitialBalance()));
}
// Event Sourcing Handler: Logic to update state from event
@EventSourcingHandler
public void on(AccountCreatedEvent event) {
this.accountId = event.getId();
this.balance = event.getBalance();
}
}Event sourcing vs CRUD
| Feature | CRUD Microservices | Event Sourced Microservices |
|---|---|---|
| Source of Truth | Current state in a DB | Sequence of immutable events |
| History | Needs separate audit tables | History is the data (native audit) |
| Data Loss | Overwrites previous values | No data is ever deleted/overwritten |
| Querying | Direct and simple | Requires Projections (CQRS) |
| Scaling | Scaling DB locks/contention | Highly scalable append-only writes |