Saltar al contenido principal
Home
HexagonalGuru

CQRS y Event-Driven: Cuándo Merecen la Pena y Cuándo son Sobreingeniería

Avatar de HexagonalGuru

HexagonalGuru

CQRS y Event-Driven: Cuándo Merecen la Pena y Cuándo son Sobreingeniería

Un equipo de cinco personas mantiene un CRUD de facturas. Seis meses después de que alguien leyera un libro de arquitectura, el sistema tiene dos bases de datos, un broker de eventos, nueve proyecciones y un diagrama que ya nadie sabe dibujar de memoria. La facturación sigue haciendo exactamente lo mismo que antes — solo que ahora tarda más en cambiar y falla de formas nuevas y emocionantes.

CQRS y la arquitectura orientada a eventos son dos de las herramientas más potentes del repertorio moderno. También son de las más abusadas. Esta guía va de lo segundo: qué son sin evangelismo, qué señales indican que las necesitas de verdad y cómo adoptarlas por etapas sin hipotecar al equipo.

Qué Son, en una Frase Cada Una

CQRS (Command Query Responsibility Segregation): el modelo que escribe y el modelo que lee son cosas distintas. Las operaciones que cambian estado (comandos) usan un modelo optimizado para proteger reglas de negocio; las consultas usan otro optimizado para devolver datos rápido y con la forma exacta que cada pantalla necesita.

Arquitectura orientada a eventos (event-driven): los componentes no se llaman entre sí directamente; anuncian hechos — «FacturaEmitida», «PedidoCancelado» — y quien los necesita reacciona. El emisor no sabe quién escucha, y eso es precisamente lo que lo hace potente.

Y una precisión que ahorra mucho dinero: no son un pack. CQRS no exige eventos y los eventos no exigen CQRS. Comprarlos juntos «porque van de la mano» es como comprar el remolque antes de tener el coche.

Lo Que Cambia de Verdad (y Lo Que No)

Diagrama de arquitectura CQRS: el lado de comandos valida reglas de negocio y escribe en su base de datos, los eventos actualizan las proyecciones y el lado de consultas lee de modelos optimizados

Cuando la decisión es correcta, esto es lo que cambia:

  • Las lecturas dejan de pelear con las escrituras. El listado de facturas con doce filtros y tres totales ya no comparte modelo con la lógica que valida que una factura emitida no se puede editar. Cada lado evoluciona a su ritmo.
  • La escritura se concentra en las reglas. El modelo de comandos no arrastra DTOs de pantalla ni consultas: existe para proteger invariantes. Es el lugar donde DDD brilla — si tu dominio lo justifica, como contamos en la guía práctica de Domain-Driven Design.
  • Los eventos desacoplan en el tiempo. Si el servicio que envía el email de confirmación está caído, el pedido se confirma igual; el evento espera. Las averías dejan de propagarse en cadena.
  • Cada consumidor crece sin molestar. Mañana aparece un informe nuevo, una integración con contabilidad o una auditoría: se suscriben a los eventos que ya existen sin tocar el código que los emite.

Y lo que no cambia — o cambia a peor si lo ignoras: la consistencia pasa de inmediata a eventual («el pedido ya está, el listado lo verá en un segundo»), depurar exige seguir mensajes entre sistemas, la infraestructura crece (broker, proyecciones, consumidores) y el equipo necesita oficio. CQRS y eventos no eliminan la complejidad: la trasladan a un lugar donde solo merece estar si te da algo a cambio.

Las Señales de que Sí

CQRS paga sus facturas cuando se dan varias de estas condiciones a la vez:

  • Reglas de escritura complejas. Cambiar estado implica validar invariantes serios, no un «guarda el formulario». Si tu lógica de escritura cabe en un controlador, no necesitas un modelo de comandos.
  • Lecturas con formas radicalmente distintas. El mismo concepto se consulta como listado paginado, informe agregado, API pública y exportación a Excel — y cada consulta tortura al modelo de escritura un poco más.
  • Desproporción brutal entre lectura y escritura. Miles de lecturas por cada escritura justifican optimizar cada lado por separado, incluso con almacenes distintos.
  • Varios consumidores del mismo hecho. Cuando «PedidoConfirmado» debe disparar email, almacén, facturación y analítica, el evento es la forma natural; encadenar llamadas síncronas es una bomba de acoplamiento.
  • Trazabilidad como requisito. Si negocio o regulación exigen saber qué pasó y cuándo, los eventos te dan el historial casi gratis (y el event sourcing, que es otro paso más y casi nunca necesario, te da el historial completo).

Las Señales de que No

La sobreingeniería también tiene sus síntomas, y son igual de reconocibles:

  • Un CRUD disfrazado. Crear, leer, actualizar, borrar — sin reglas de negocio que proteger. Meter CQRS aquí es comprar un camión para llevar la mochila al trabajo.
  • Equipo pequeño, patrón nuevo. Si nadie ha operado eventos en producción, el primer sistema event-driven del equipo no debería ser crítico. La curva de aprendizaje se paga en incidentes.
  • La consistencia inmediata es obligatoria. Si el usuario debe ver su cambio reflejado en el mismo instante y no hay margen para «eventual», las proyecciones asíncronas son un problema, no una solución.
  • «Por si escalamos». Escalar de verdad es un problema estupendo que se resuelve cuando llega, con métricas en la mano. Diseñar para el tráfico que imaginas en vez del que tienes es la forma más cara de adivinar el futuro.

El Camino Incremental (Párate Donde Deje de Aportar)

La mayor trampa no es técnica: es adoptar el patrón completo de golpe. El camino sano tiene cuatro peldaños, y cada uno aporta valor aunque nunca subas al siguiente:

Escalera de adopción incremental de CQRS y eventos: separar código de lectura y escritura, luego modelos separados sobre la misma base de datos, después proyecciones con almacenamiento propio y por último un broker de eventos con varios consumidores
  1. Separar el código de lectura y de escritura. Mismo modelo, misma base de datos, pero los handlers de comandos no devuelven datos de pantalla y las consultas no tocan el modelo de dominio. Cuesta un día de disciplina y ya aclara la arquitectura.
  2. CQRS-lite: dos modelos, una base de datos. Las consultas usan SQL directo o vistas con DTOs a medida; los comandos usan el modelo rico. Sin broker, sin proyecciones, sin infraestructura nueva. Aquí viven felices la mayoría de las aplicaciones que «necesitaban CQRS».
  3. Proyecciones con almacenamiento propio. Cuando las lecturas exigen formas o volumen que la base transaccional no da, se alimentan proyecciones desde eventos internos. Aparece la consistencia eventual: introdúcela solo donde negocio la acepta.
  4. Eventos con broker y consumidores múltiples. Cuando hay varios sistemas reaccionando a los mismos hechos, entra el broker (RabbitMQ, Kafka, lo que encaje en tu operación). No antes: un broker sin consumidores múltiples es una cola con delirios de grandeza.

Que este camino sea barato de recorrer no es casualidad: es exactamente lo que facilita la arquitectura hexagonal. Si puertos y adaptadores aíslan el dominio de la infraestructura, cambiar «evento interno» por «evento en RabbitMQ» es cambiar un adaptador, no reescribir el sistema.

Errores Comunes

  1. CQRS en todo el sistema. El patrón se aplica por bounded context, no por aplicación. La facturación puede necesitarlo y el catálogo de países, no. Un sistema sano mezcla: CQRS donde duele, CRUD donde sobra.
  2. Event sourcing de regalo. Guardar el historial completo de eventos como fuente de verdad es un patrón distinto, mucho más exigente, que CQRS no requiere. Si alguien lo propone, que explique qué regulación o qué análisis temporal lo justifica.
  3. Eventos que son RPC disfrazado. Si el emisor espera una respuesta del «evento», eso es una llamada remota con latencia extra. Los eventos anuncian hechos pasados; los comandos piden acciones futuras. Confundirlos rompe el modelo mental entero.
  4. Consistencia eventual sin avisar a negocio. El usuario que paga y no ve el pago en su panel durante dos segundos llamará a soporte. La UI debe diseñar para la eventualidad: estados «procesando», confirmaciones por email, refrescos. Es una decisión de producto, no solo técnica.
  5. Broker sin vigilancia. Una cola que crece sin alertas es un incidente madurando en silencio. Lag de consumidores, mensajes muertos y reintentos son métricas de primer nivel desde el día uno.

En Resumen

CQRS separa escritura de lectura; los eventos convierten llamadas en hechos. Merecen la pena cuando hay reglas de escritura complejas, lecturas exigentes, desproporción de carga o varios consumidores del mismo hecho — y son sobreingeniería en un CRUD, en un equipo sin oficio o cuando la consistencia inmediata es sagrada. El camino sano es incremental: separar código, separar modelos, proyectar, y solo entonces broker. Cada peldaño aporta; el error es querer subir la escalera de un salto.

Si sospechas que tu sistema necesita este salto — o que ya lo dio y ahora nadie entiende nada — una auditoría de arquitectura lo deja claro en días, con un plan por etapas. Hablemos de tu caso →

Sigue leyendo: Qué es Domain-Driven Design: guía práctica con un ejemplo real.

  • #ddd
  • #cqrs
  • #event-driven

Artículos relacionados

¿Empezamos?

¿Listo para construir algo que crezca con tu negocio?

Cuéntanos tus objetivos y trazaremos juntos la ruta de diseño, desarrollo y tecnología que te lleve de la visión a resultados medibles.