Command Palette

Search for a command to run...

ES·EN

Nivel 3 · 30 min

CQRS con Eventos

CQRS (Command Query Responsibility Segregation) separa el modelo de escritura (comandos que mutan estado) del modelo de lectura (queries que devuelven datos). Combinado con una arquitectura event-driven, los domain events del lado de escritura impulsan proyecciones en el lado de lectura. Esto habilita escala masiva y flexibilidad a costa de consistencia eventual.

Split Comando-Query

En arquitecturas tradicionales, el mismo modelo sirve lecturas y escrituras — optimizar uno limita al otro. CQRS los separa: los comandos (CreateOrder, UpdatePaymentStatus) mutan estado via el write model. Los queries (GetOrderSummary, ListCustomerOrders) leen del read model. Cada uno puede usar almacenamiento diferente — el write model puede usar una DB relacional normalizada para integridad; el read model usa tablas denormalizadas, Elasticsearch o Redis para queries rápidas. Los command handlers validan, aplican reglas de negocio y emiten domain events. Los query handlers simplemente leen del read store.

Proyecciones del Read Model

Las proyecciones son event handlers que consumen domain events y actualizan el read model. Cuando se dispara OrderPlaced, la OrderSummaryProjection crea una nueva fila en la tabla order_summaries. Cuando se dispara PaymentReceived, actualiza el payment_status. Las proyecciones se reconstruyen desde cero reproduciendo todos los eventos — habilitando evolución de esquema sin migraciones. Cada proyección está optimizada para un patrón de query específico — OrderByCustomerProjection construye un índice cliente → pedidos; OrderAnalyticsProjection agrega en estadísticas diarias. Múltiples proyecciones de los mismos eventos sin acoplamiento.

Consistencia Eventual e Integración

El write model y los read models tienen consistencia eventual — hay un delay entre que un comando es procesado y el read model lo refleja. En la práctica suele ser millisegundos pero puede ser mayor bajo carga. Manejalo en la UI: actualizaciones optimistas (asumir éxito y mostrar el nuevo estado inmediatamente), consistencia read-your-writes (consultar el write model directamente para el ítem que el usuario acaba de modificar), o mensajería UX (''Tu pedido está siendo procesado...''). Integración con mensajería: domain events publicados a Kafka; projection workers consumen y actualizan read stores. Múltiples servicios independientes pueden construir sus propias proyecciones del mismo topic Kafka.

Puntos clave

  • CQRS permite que write y read models usen tecnologías de almacenamiento completamente diferentes — cada una optimizada para su carga de trabajo.
  • Las proyecciones son vistas derivadas — pueden reconstruirse desde eventos en cualquier momento, haciendo la evolución de esquema barata.
  • La consistencia eventual es la complejidad principal — diseñá tu UX para manejar el lag graciosamente en lugar de ocultarlo.

Code example

// Command handler: write model
@CommandHandler
void handle(CreateOrderCommand cmd) {
  Order order = Order.create(cmd); // validar + emitir eventos
  eventStore.save(order.getUncommittedEvents());
  eventBus.publish(order.getUncommittedEvents());
}

// Projection handler: actualizar read model
@EventHandler
void on(OrderPlaced event) {
  orderSummaryRepo.save(OrderSummaryView.from(event));
}