Cada sistema tiene una arquitectura, aunque nadie la haya diseñado. La diferencia es si la elegiste tú o si fue el resultado accidental de cientos de decisiones pequeñas. Y esas decisiones se cobran tarde: cuando el equipo crece, cuando llega un cliente grande o cuando una funcionalidad “sencilla” tarda tres sprints porque toca medio sistema.
Estas son las ideas que aplicamos al diseñar plataformas que necesitan crecer.
La arquitectura es un problema de cambio
Una buena arquitectura no es la que tiene más diagramas ni la que usa la tecnología de moda. Es la que permite cambiar el sistema con poco riesgo y poco costo. Por eso la primera pregunta no es técnica: ¿qué partes del negocio van a cambiar más en los próximos dos años?
Las reglas de precios, los medios de pago o las integraciones con terceros suelen cambiar mucho. La gestión de usuarios o la facturación base, bastante menos. La arquitectura debe aislar lo volátil para que su evolución no arrastre al resto.
Empieza con un monolito modular
Para la mayoría de productos nuevos recomendamos un monolito modular: una sola aplicación desplegable, dividida internamente en módulos con límites estrictos.
src/
facturacion/ → dominio, casos de uso, adaptadores
inventario/
clientes/
compartido/ → solo utilidades sin lógica de negocio
Cada módulo expone una interfaz pública y oculta su implementación. Ningún módulo lee directamente las tablas de otro. Con esa disciplina obtienes casi todos los beneficios de los microservicios (equipos independientes, código entendible) sin pagar su costo operativo: redes que fallan, consistencia eventual, trazas distribuidas y despliegues coordinados.
Los microservicios resuelven un problema de organización, no de rendimiento. Si no tienes varios equipos que se bloquean entre sí, probablemente todavía no los necesitas.
Cuándo sí separar un servicio
Extraer un módulo a un servicio independiente tiene sentido cuando se cumple al menos una de estas condiciones:
- Escala distinta: una parte recibe diez o cien veces más carga que el resto (por ejemplo, la ingesta de eventos o la búsqueda).
- Ritmo de cambio distinto: un equipo necesita desplegar varias veces al día sin esperar al resto.
- Requisitos técnicos distintos: un proceso de machine learning en Python junto a un backend en Node.js, o un componente con exigencias de seguridad especiales.
Si los límites del monolito modular están bien definidos, esa extracción es un trabajo de semanas, no una reescritura.
Capas: el dominio en el centro
Dentro de cada módulo separamos tres responsabilidades:
- Dominio: las reglas del negocio, sin dependencias de frameworks, bases de datos ni APIs externas. Es el código más valioso y el más fácil de probar.
- Aplicación: los casos de uso que orquestan el dominio (“emitir factura”, “reservar inventario”).
- Infraestructura: base de datos, colas, proveedores externos. Se conecta al dominio mediante interfaces.
La regla de oro: las dependencias apuntan hacia el dominio. Cambiar de proveedor de pagos o de base de datos debería tocar un adaptador, no tus reglas de negocio.
Datos: el acoplamiento que nadie ve
El acoplamiento más peligroso no está en el código, sino en la base de datos. Cuando cinco módulos leen y escriben la misma tabla, cualquier cambio de esquema se vuelve una negociación.
Algunas prácticas que nos funcionan:
- Cada módulo es dueño de sus tablas; los demás consultan a través de su interfaz.
- Para comunicar cambios entre módulos usamos eventos de dominio (“FacturaEmitida”), con el patrón outbox cuando necesitamos garantizar que el evento se publique.
- Las migraciones son compatibles hacia atrás: primero se agrega, luego se migra y al final se elimina.
Decisiones documentadas
Cada decisión importante queda registrada en un ADR (Architecture Decision Record): una página con el contexto, las opciones evaluadas, la decisión y sus consecuencias. Seis meses después, cuando alguien pregunte “¿por qué hicimos esto así?”, la respuesta existe y no depende de la memoria de nadie.
Observabilidad desde el primer despliegue
No puedes escalar lo que no puedes ver. Desde la primera versión incluimos:
- Logs estructurados con un identificador de solicitud que atraviesa todo el sistema.
- Métricas de negocio y técnicas: pedidos por minuto, latencia p95, tasa de errores.
- Alertas basadas en síntomas que siente el usuario, no en cada pico de CPU.
Lista de verificación
Antes de dar por buena una arquitectura, revisamos:
- ¿Podemos explicar los límites de cada módulo en una frase?
- ¿Un desarrollador nuevo puede hacer un cambio en un módulo sin entender todo el sistema?
- ¿Podemos reemplazar un proveedor externo tocando un solo adaptador?
- ¿Sabemos, con datos, cuál es el cuello de botella actual?
La arquitectura no se diseña una vez: se cuida en cada sprint. Si tu plataforma se está volviendo lenta de cambiar, hablemos y revisamos juntos por dónde empezar.