De monolitos a microservicios (y ahora a monolitos otra vez?)

En el mundo de la ingeniería de software hay dos conceptos que suelen dividir aguas cuando se habla de cómo estructurar una aplicación: monolito y microservicios. Son dos formas distintas de organizar un sistema, y si bien ambas tienen sus ventajas, también tienen sus trampas. En los últimos años, hubo una especie de fiebre por los microservicios, muchos equipos se sintieron casi obligados a romper sus aplicaciones en pedacitos, incluso cuando no era necesario, para darse cuenta de lo obvio: la simplicidad es mejor. En mi experiencia, lo que mejor funciona en la práctica no es de manual, sino un enfoque híbrido, flexible y adaptado al objetivo.

Un monolito es básicamente una aplicación única, centralizada. Todo el código vive en un solo proyecto, desde la API hasta la lógica de negocio. Es simple de entender, fácil de testear en su conjunto, y generalmente más rápido de desarrollar al principio. Pero a medida que crece, puede volverse difícil de mantener (y de compilar y publicar), especialmente si varias personas tocan partes distintas que están todas juntas.

Los microservicios, en cambio, buscan dividir el sistema en módulos más pequeños e independientes. Cada uno se encarga de una única responsabilidad: uno maneja usuarios, otro productos, otro pagos, etc. Se comunican entre sí vía API (REST, gRPC), y muchas veces tienen su propia base de datos. En la teoría, esto suena moderno y escalable. Pero en la práctica, cuando querés hacer un cambio que toca dos o tres servicios, terminás lidiando con versiones, contratos, sincronización de datos y despliegues encadenados. Y si sos un equipo chico o un proyecto en etapa temprana, eso puede ser más una carga que una ventaja.

No hace falta aplicar estos modelos de forma dogmática. De hecho, hacerlo puede llevarte directo a un caso de overengineering, donde estás resolviendo problemas que todavía no tenés, con herramientas que no necesitabas. Debemos evitar la obsesión en algunos entornos por aplicar la arquitectura correcta cuando en realidad lo más sensato suele ser lo más simple que funcione bien y sea fácil de mantener.

En mi opinión personal, lo que mejor funciona es una especie de enfoque híbrido. Podemos separar los proyectos según su función, cada uno con su lógica y estructura propia, pero no siempre es necesario desacoplarlos completamente. Es válido compartir una base de datos común y ya. Luego, para algunos casos puntuales que tengan sentido, se puede desarrollar un API, o una cola de trabajo en segundo plano. ¿Kubernetes? ¿Estás loco? Un buen flujo de CI/CD con Docker es más que suficiente por un largo tiempo. Este enfoque permite modularizar sin perder coherencia, y evita tener que reinventar la rueda con sincronizaciones innecesarias. Los servicios pueden escalar de forma separada si hace falta, pero no parto de la base de que todos tienen que ser 100% independientes desde el día cero.

Como todo en este mundillo, se trata de usar el sentido común y construir algo que tenga sentido para el tamaño del equipo, el estadio del producto, y los objetivos del negocio. Y la respuesta suele estar en el medio de lo celestial y lo mudano (!?).

Publicado el

en

, ,

¿Querés seguir la conversación?