Monólito não é palavrão

Monólito virou, em algum ponto da última década, sinônimo de arquitetura ultrapassada. Estranho, considerando que boa parte dos problemas que microsserviços resolvem só existe numa escala que a maioria das aplicações nunca chega perto de alcançar.

O que “monólito” realmente descreve

Monólito descreve uma aplicação implantada como uma única unidade: um processo, um deploy, um banco de dados (ou pelo menos um esquema compartilhado), mesmo que internamente o código esteja organizado em módulos bem separados. A confusão comum é tratar “monólito” como sinônimo de “código mal organizado”, quando na verdade a característica que define monólito é a unidade de implantação, não a qualidade da organização interna.

Monólito modular: separação sem distribuição

Um monólito modular aplica separação de responsabilidade dentro da mesma aplicação, geralmente organizada em torno de bounded contexts, um conceito de Domain-Driven Design que define fronteira clara de significado e responsabilidade dentro do domínio. Cada módulo tem sua própria área de responsabilidade, a comunicação entre módulos acontece através de interface bem definida dentro do próprio processo, e nenhuma dessas fronteiras exige uma chamada de rede para ser respeitada.

Isso entrega boa parte do benefício organizacional que costuma ser atribuído a microsserviços (limite claro, responsabilidade isolada, times conseguindo trabalhar em áreas diferentes sem pisar uns nos outros) sem pagar o custo de rede, serialização e coordenação distribuída entre serviços separados.

O preço que microsserviços cobram, e que nem sempre aparece na conversa

Separar um sistema em microsserviços transforma o que era uma chamada de método, dentro do mesmo processo, em uma chamada de rede: sujeita a latência, falha parcial, timeout e necessidade de tratamento explícito para cada uma dessas possibilidades que uma chamada local simplesmente não tinha.

Isso também traz complexidade operacional real: descoberta de serviço, versionamento de contrato entre serviços que evoluem em ritmos diferentes, observabilidade espalhada por múltiplos processos (rastrear uma requisição que passa por cinco serviços exige tracing distribuído, não só um log local), e transação que antes era atômica dentro de um banco e agora precisa lidar com consistência eventual entre serviços diferentes.

Nada disso é hipotético ou exagero. É o preço de trocar um processo por vários, e esse preço existe independentemente de a aplicação ter ou não a escala que justificaria pagá-lo.

Quando a separação distribuída realmente compensa

Microsserviços fazem mais sentido quando existe uma razão concreta para a separação física: times grandes o suficiente para precisarem de fronteira de deploy independente entre si, parte do sistema com necessidade real de escalar separadamente (uma área com volume de tráfego ordens de magnitude maior que o resto), ou requisito de disponibilidade e isolamento de falha que realmente exige que um componente continue funcionando mesmo com outro completamente fora do ar.

Fora desses cenários, a separação física tende a adicionar complexidade operacional sem um ganho equivalente, só porque “é assim que sistema moderno é feito”.

Monólito primeiro não é atalho, é sequência razoável

Existe uma recomendação conhecida na indústria de começar por um monólito bem modularizado, e migrar partes específicas para serviços separados apenas quando um limite real de escala ou organização aparecer, em vez de nascer distribuído por antecipação de um problema que talvez nunca chegue a existir. Isso não é preguiça arquitetural. É reconhecer que fronteira de módulo dentro de um processo é muito mais barata de errar e corrigir do que fronteira de serviço já implantada como rede separada.

Simplicidade também é uma escolha de arquitetura

Escolher monólito modular não é ausência de decisão arquitetural, é uma decisão arquitetural, tão válida quanto escolher microsserviços quando a escala realmente pede isso. O erro não está em escolher monólito. Está em tratar essa escolha como sinal de que o projeto não amadureceu o suficiente, quando com frequência ela é exatamente a escolha mais madura disponível para o tamanho real do problema.