Comunicación entre Bounded Contexts en Code Finances (EDA en acción)
Cómo se comunican los distintos Bounded Contexts en Code Finances usando Event Driven Architecture: desacoplamiento, naming de eventos y flujos reales con RabbitMQ.
Seguimos con la serie de Code Finances y hoy entramos en un tema clave cuando trabajas con Domain Driven Design: cómo se comunican los distintos Bounded Contexts.
Porque diseñar bien los límites del dominio está muy bien… pero hacer que hablen entre ellos correctamente es otra historia.
🧩 El problema
En sistemas basados en DDD, es muy común tener múltiples contextos: Cash Flow, Liquidity Categories, Equity, Projections… Y surge la pregunta inevitable:
¿Cómo hacemos que colaboren sin acoplarlos?
🚀 La solución: Event Driven Architecture
En Code Finances optamos por una estrategia clara: arquitectura orientada a eventos.
En lugar de esto:
liquidityService.allocate(revenue)
Hacemos esto:
eventBus.publish(new RevenueCreatedEvent(...))
Un contexto publica eventos cuando cambia su estado. Otros contextos escuchan y reaccionan. Nadie depende directamente de nadie.
flowchart TB
subgraph CF[Cash Flow BC]
direction TB
UC["CreateRevenue<br/>UseCase"]
EV[RevenueCreatedEvent]
UC -->|emite| EV
end
EV -->|publica| RMQ[RabbitMQ]
RMQ --> S1
RMQ --> S2
RMQ --> S3
subgraph LC[Liquidity Categories BC]
S1["AllocateLiquidity<br/>Subscriber"]
end
subgraph EQ[Equity BC]
S2["UpdateEquity<br/>Subscriber"]
end
subgraph PR[Projections BC]
S3["RecalcProjections<br/>Subscriber"]
end
style CF fill:#1e1b4b,stroke:#818cf8,color:#e0e7ff
style LC fill:#1e1b4b,stroke:#818cf8,color:#e0e7ff
style EQ fill:#1e1b4b,stroke:#818cf8,color:#e0e7ff
style PR fill:#1e1b4b,stroke:#818cf8,color:#e0e7ff
style RMQ fill:#0f172a,stroke:#818cf8,color:#e0e7ff
✅ Ventajas
- 🔌 Desacoplamiento fuerte entre contextos
- 📈 Escalabilidad independiente
- 🛡 Mayor resiliencia
- 🔄 Flexibilidad para evolucionar
- ⚡️ Procesamiento asíncrono
❌ Retos reales
EDA no es magia, también tiene costes:
- 🧠 Mayor complejidad
- 🔁 Duplicación de eventos o problemas de orden
- ⏳ Consistencia eventual
- 🎯 Diseñar bien los eventos es crítico
🧩 Naming de eventos
Una de las decisiones más importantes: cómo nombras tus eventos. En Code Finances seguimos estas convenciones:
🔑 Eventos de dominio
application.bounded_context.version.event.aggregate.action
Ejemplo:
code_finances.cash_flow.1.event.revenue.created
👂 Colas / handlers
bounded_context.aggregate.action_on_domain_event
Ejemplo:
liquidity_categories.liquidity_category.allocate_liquidity_categories_on_revenue_created
Esto nos da claridad semántica, versionado explícito, mejor organización de topics/routing keys y alineación total con DDD + EDA.
Los eventos se nombran en pasado porque representan algo que ya ha ocurrido.
🧶 Caso práctico: Create Revenue → Allocate Liquidity → Process Projection
2.
RevenueCreator procesa el caso de uso3. Publica
RevenueCreatedEvent en RabbitMQ── reacciones ──
💧 Liquidity Categories consume el evento → distribuye según porcentajes
📊 Equity actualiza el total de liquidez
📋 Projections marca el evento como procesado
Una acción simple como "crear un revenue" puede desencadenar múltiples procesos — sin acoplamiento, de forma escalable, respetando cada contexto.
💬 Conclusión
EDA no es solo una decisión técnica. Es una forma de diseñar sistemas donde los contextos son realmente independientes, el dominio fluye a través de eventos y el sistema puede crecer sin romperse.
Eso sí: requiere disciplina, especialmente en el diseño de eventos, el naming y la gestión de consistencia. Pero cuando encaja… es extremadamente potente.
Publicado originalmente en LinkedIn.