
La arquitectura no se elige para que el diagrama parezca sofisticado. Se elige para que el producto pueda cambiar sin convertir cada entrega, fallo o decisión de negocio en un problema mayor.
Monolito modular, microservicios y arquitectura orientada a eventos aparecen constantemente en sistemas modernos, pero no son tres casillas equivalentes. Los dos primeros definen dónde viven y se despliegan los límites; los eventos definen cómo se comunican algunas partes.
La arquitectura adecuada minimiza el costo total de cambiar, operar y entender el sistema.
01. Tres patrones que pueden convivir
Antes de elegir, separa tres decisiones:
Tres decisiones independientes de arquitectura: límites de código, despliegue y comunicación
| Decisión | Pregunta | Opciones comunes |
|---|---|---|
| límites de código | ¿qué parte puede conocer a cuál? | módulos, capas, puertos y adaptadores |
| límites de despliegue | ¿qué puede publicarse de forma independiente? | monolito modular, servicios |
| comunicación | ¿la respuesta debe ser inmediata? | llamada síncrona, mensaje, evento |
Un monolito puede publicar eventos. Un ecosistema de microservicios puede usar llamadas síncronas. Un producto maduro puede combinar un núcleo modular, dos servicios extraídos y varios consumidores asíncronos.
La pregunta no es cuál patrón “gana”, sino qué independencia necesita realmente cada parte.
02. Monolito modular: un despliegue, límites explícitos
El monolito modular mantiene una sola unidad desplegable y divide el dominio en módulos con contratos claros. orders, catalog, billing e identity pueden compartir proceso y repositorio sin compartir libremente su lógica interna.
| Ventaja | Por qué importa |
|---|---|
| cambios coordinados | una refactorización puede cruzar módulos en una sola entrega |
| transacciones simples | muchas reglas pueden ejecutarse en una misma base de datos |
| operación compacta | menos pipelines, redes, credenciales y puntos de fallo |
| feedback rápido | el equipo aprende el dominio sin congelar límites prematuros |
Es un buen punto de partida cuando el producto cambia rápido, el equipo es pequeño o mediano y todavía no existe una razón operativa para distribuirlo.
El riesgo no es ser monolito; es perder la modularidad. Imports cruzados, tablas usadas como API y cambios que atraviesan todo el sistema indican que los límites existen solo en el diagrama. Pruebas de arquitectura, ownership y contratos internos deben protegerlos.
03. Microservicios: independencia con impuesto operativo
Un microservicio posee una capacidad concreta, puede desplegarse de forma independiente y controla su contrato y sus datos. Separar procesos sin separar ownership, despliegue o persistencia solo crea un monolito distribuido.
La extracción tiene sentido cuando aparece una necesidad verificable:
Extracción selectiva de una capacidad desde el núcleo modular y su nuevo costo operativo
- equipos que deben entregar sin coordinar cada release;
- cargas con perfiles de escala claramente distintos;
- requisitos específicos de disponibilidad, seguridad o aislamiento;
- ciclos de cambio que ya no encajan en el despliegue principal.
Cada servicio añade red, latencia, autenticación, versionado, observabilidad, retries y modos de fallo parciales. Antes de multiplicarlos, el equipo necesita automatización de despliegue, métricas, logs correlacionados, trazas, contratos versionados y ownership operativo.
La unidad correcta no es “una tabla por servicio” ni “un endpoint por servicio”. Es una capacidad de negocio que puede evolucionar y fallar con suficiente independencia.
04. Event-driven: desacoplar el momento de reaccionar
Una arquitectura orientada a eventos publica hechos que ya ocurrieron: OrderPlaced, PaymentConfirmed o ArticlePublished. Los consumidores reaccionan sin que el productor tenga que conocerlos ni esperar su respuesta.
Flujo event-driven con productor, consumidores, idempotencia, reintentos y dead-letter queue
Eso resulta útil para notificaciones, analítica, sincronización, workflows extensos y picos de carga. También puede conectar módulos dentro de un monolito o servicios separados.
| Llamada síncrona | Evento asíncrono |
|---|---|
| el emisor necesita una respuesta ahora | el emisor anuncia un hecho |
| el flujo es directo y fácil de seguir | varios consumidores reaccionan por separado |
| la disponibilidad del receptor afecta la solicitud | una cola puede absorber indisponibilidad temporal |
| consistencia inmediata más sencilla | requiere aceptar y diseñar consistencia eventual |
Los eventos no eliminan el acoplamiento: lo trasladan al contrato del mensaje. Producción real exige idempotencia, retries con límite, dead-letter queue, versionado, observabilidad y una política explícita de orden y duplicados.
05. Una arquitectura híbrida, paso a paso
Imagina una plataforma de comercio que comienza como monolito modular. orders, catalog e identity viven en un despliegue, cada uno detrás de su contrato.
Cuando la búsqueda necesita indexación y escala propias, se extrae como servicio. Cuando un pedido se confirma, el módulo de órdenes guarda la transacción y publica OrderPlaced. Inventario, email y analítica procesan el evento de forma independiente.
El resultado no es una migración total a microservicios. Es una composición deliberada:
| Parte | Patrón | Razón |
|---|---|---|
| núcleo transaccional | monolito modular | coherencia y cambios rápidos |
| búsqueda | servicio independiente | infraestructura y escala específicas |
| notificaciones y analítica | consumidores de eventos | no deben bloquear la compra |
Este modelo permite extraer solo donde el beneficio supera el costo, mientras conserva simples las partes que no necesitan autonomía.
06. Matriz de decisión
| Señal dominante | Empieza o continúa con | Condición necesaria |
|---|---|---|
| dominio todavía cambiante | monolito modular | límites internos verificables |
| despliegues coordinados frenan equipos | microservicios selectivos | ownership y plataforma operativa |
| una carga necesita escalar o aislarse | servicio independiente | métricas que demuestren la diferencia |
| procesos secundarios bloquean al usuario | eventos | idempotencia y retries |
| múltiples consumidores reaccionan al mismo hecho | eventos | contratos versionados y trazabilidad |
| transacciones distribuidas frecuentes | reconsiderar el corte | límites de dominio probablemente incorrectos |
No uses tamaño de código como criterio principal. Evalúa autonomía de equipo, tasa de cambio, aislamiento, consistencia, latencia y capacidad operativa.
07. Una ruta de evolución segura
Evolución medida desde un monolito modular hacia un servicio extraído y consumidores de eventos
- Modela capacidades y protege límites dentro del código.
- Mantén un solo despliegue mientras la coordinación siga siendo barata.
- Instrumenta tiempos, fallos, ownership y frecuencia de cambios.
- Extrae una capacidad cuando exista dolor medible, no por anticipación.
- Agrega eventos donde la reacción pueda ser asíncrona y tolerar consistencia eventual.
- Revisa periódicamente si cada límite todavía reduce complejidad.
La arquitectura hexagonal ayuda a mantener el dominio independiente de frameworks, bases de datos y transporte tanto dentro de un monolito como dentro de un servicio. La desarrollamos con más detalle en Arquitectura hexagonal para aplicaciones web modernas.
La decisión más madura suele ser menos dramática de lo que promete un diagrama: empieza modular, distribuye solo las capacidades que necesitan independencia y usa eventos cuando el tiempo de reacción también deba desacoplarse.