Nivel 3 · 30 min
Event Sourcing
Event Sourcing almacena el estado de la aplicación como una secuencia inmutable de eventos en lugar de una snapshot del estado actual. El estado actual se deriva replayando los eventos. Esta inversión tiene consecuencias profundas en auditabilidad, debugging y capacidad de evolución.
Event Log Append-Only
En lugar de UPDATE orders SET status=''shipped'', almacenás un evento OrderShipped. El event store es append-only —nunca se modifica ni elimina eventos. Para reconstruir el estado actual de una orden, reproducís todos sus eventos en orden. El event store es la única fuente de verdad (source of truth). Esto provee un audit log completo e inmutable.
Replay y Snapshots
El replay de eventos permite reconstruir el estado en cualquier punto del tiempo —invaluable para debugging y compliance. Para aggregates con miles de eventos, los snapshots periódicos aceleran la reconstrucción: snapshot en evento 1000 + replay de los últimos 50 eventos.
Versionamiento de Eventos
Los eventos son inmutables pero el esquema evoluciona. Estrategias: Upcasting (transformar eventos viejos al esquema nuevo al leerlos), Versioned Events (mantener ambas versiones de handlers), Copy-and-Transform (migrar a un nuevo event store con formato actualizado). El versionamiento es el desafío técnico más complejo de Event Sourcing.
Code example
// Eventos inmutables
record OrderPlaced(String orderId, String customerId, Instant at) {'}
record PaymentReceived(String orderId, String paymentId, BigDecimal amount, Instant at) {'}
record OrderShipped(String orderId, String trackingNumber, Instant at) {'}
// Aggregate reconstruido desde eventos
class Order {
static Order reconstitute(List<DomainEvent> events) {
Order order = new Order();
events.forEach(order::apply);
return order;
}
private void apply(DomainEvent event) {
switch (event) {
case OrderPlaced e -> { this.id = e.orderId(); this.status = PENDING; }
case PaymentReceived e -> { this.status = PAID; }
case OrderShipped e -> { this.status = SHIPPED; }
default -> {'}
}
}
}