patterntypescriptModerate
Event sourcing: store state as an append-only log of domain events
Viewed 0 times
event sourcingappend-onlydomain eventsaggregaterehydrationsnapshotaudit logtime travel
Problem
Traditional CRUD overwrites state, losing history. Audits, debugging production incidents, and replaying business processes are painful or impossible when you only have the current state.
Solution
Instead of storing the current state, store every state-changing event. The current state is derived by replaying events. Use snapshots for performance when the event log grows long.
class OrderAggregate {
private events: DomainEvent[] = [];
place(items: Item[]): void {
this.apply(new OrderPlaced({ items, timestamp: new Date() }));
}
private apply(event: DomainEvent): void {
this.events.push(event);
this.mutate(event);
}
static rehydrate(events: DomainEvent[]): OrderAggregate {
const agg = new OrderAggregate();
events.forEach(e => agg.mutate(e));
return agg;
}
}Why
The event log is a complete audit trail. You can replay events to rebuild state, project into new read models, or time-travel debug. The append-only log is also naturally durable and scalable.
Gotchas
- Event schema evolution is hard — once events are stored, you cannot change their shape retroactively without a migration strategy
- Rehydration from thousands of events is slow — add periodic snapshots
- Aggregate boundaries determine event ownership — model them carefully before you commit
- Do not conflate event sourcing with event-driven architecture — they are complementary but distinct
Context
Systems requiring full audit trails, temporal queries, or multiple read projections from the same data
Revisions (0)
No revisions yet.