Command Palette

Search for a command to run...

ES·EN

Nivel 3 · 30 min

Event Sourcing

Event Sourcing almacena el estado de un sistema como una secuencia ordenada de domain events inmutables en lugar del estado actual. El estado actual se deriva reproduciendo los eventos. Esto desbloquea queries temporales, historial de auditoría completo y proyecciones desacopladas — a costa de complejidad y consistencia eventual.

Event Store y Append-Only

El event store es un log append-only de domain events. Los eventos son hechos inmutables en tiempo pasado: OrderPlaced, PaymentReceived, OrderShipped. Nunca actualizás ni eliminás eventos — solo agregás nuevos. El estado actual de un agregado se deriva reproduciendo sus eventos en orden. Esto significa que tenés una historia completa por diseño. Implementaciones de event store: EventStoreDB (propósito específico), PostgreSQL (tabla events con stream_id + version), Kafka (topics compactados), o AWS DynamoDB Streams.

Event Replay y Proyecciones

El event replay reconstruye el estado de un agregado aplicando eventos secuencialmente. Al iniciar, cargar todos los eventos para un aggregate ID y aplicarlos a un objeto de estado vacío. Las proyecciones (read models) se construyen consumiendo el stream de eventos y construyendo vistas denormalizadas optimizadas para queries. Múltiples proyecciones pueden construirse del mismo stream de eventos — una proyección OrderSummary, una OrderByCustomer, una Analytics — todas de los mismos eventos OrderPlaced/OrderShipped. Las proyecciones pueden reconstruirse desde cero reproduciendo todos los eventos — poderoso para migraciones de esquema.

Snapshots y Versionado de Eventos

Los snapshots capturan el estado del agregado en un punto en el tiempo, almacenado junto a los eventos. Al cargar: obtener último snapshot + reproducir solo los eventos desde el snapshot. Esencial para agregados con miles de eventos. El versionado de eventos es un desafío crítico: ¿qué pasa cuando el esquema de un evento cambia? Upcasting: transformar versiones antiguas del evento a la versión actual al leer. Estrategias de versionado: schema registry, nombres de evento versionados (OrderPlacedV2), o upcasters en runtime.

Puntos clave

  • Los eventos son hechos inmutables — nunca se actualizan. La restricción append-only es lo que habilita el time travel y los audit logs.
  • Las proyecciones se reconstruyen desde eventos — esto hace las migraciones de esquema triviales (reconstruir desde cero con nuevo esquema) a costa del tiempo de reconstrucción.
  • Los snapshots son una optimización, no un requisito — agregalos cuando el rendimiento del replay se convierte en problema, no prematuramente.

Code example

// Agregado event-sourced
class OrderAggregate {
  private String id;
  private OrderStatus status;
  private List<DomainEvent> uncommittedEvents = new ArrayList<'>();
  
  // Reconstruir desde eventos
  static OrderAggregate rehydrate(List<DomainEvent> events) {
    OrderAggregate order = new OrderAggregate();
    events.forEach(order::apply);
    return order;
  }
  void placeOrder(PlaceOrderCommand cmd) {
    apply(new OrderPlaced(cmd.getOrderId(), cmd.getItems()));
  }
  private void apply(OrderPlaced event) {
    this.id = event.getOrderId();
    this.status = OrderStatus.PLACED;
    uncommittedEvents.add(event);
  }
}