Todo projeto novo chega, cedo ou tarde, nessa encruzilhada: "vamos de monolito ou de microsserviços?". E toda vez que essa pergunta aparece numa reunião de arquitetura, eu sinto o mesmo desconforto: a maioria das pessoas já entrou na sala com a resposta decidida antes mesmo da pergunta ser feita. E, quase sempre, a resposta é "microsserviços", porque isso soa mais moderno, mais "Netflix", mais currículo bonito.

Só que arquitetura não é sobre o que soa impressionante no LinkedIn. É sobre o que faz o seu time entregar valor sem se afogar em complexidade que ele ainda não sabe administrar. E depois de acompanhar (e sofrer com) vários sistemas corporativos, minha conclusão é bem direta: na imensa maioria dos casos, o melhor ponto de partida não são os microsserviços — é o Monolito Modular.

Não é modinha, não é regra absoluta e não é "microsserviços são ruins". É outra coisa: arquitetura distribuída é uma conta cara, e a maioria dos times decide pagar essa conta antes mesmo de entender direito o que está comprando.
 

O erro clássico: distribuir o sistema antes de entender o domínio

Microsserviços vendem uma promessa sedutora: deploy independente, times autônomos, escalabilidade seletiva, isolamento de falhas, liberdade para escolher stack por serviço. Tudo isso é real. O problema é que ninguém coloca no anúncio o preço disso.

Porque microsserviços não dividem só código — eles importam para dentro do seu projeto um pacote inteiro de complexidade que antes nem existia:

  • comunicação via rede, com toda a latência e instabilidade que isso implica;
  • retries, timeouts e o inevitável "e se esse serviço não responder?";
  • falhas parciais — parte do sistema no ar, parte fora, e você tendo que lidar com isso graciosamente;
  • rastreamento distribuído, porque um simples log deixou de ser simples;
  • consistência eventual e coreografia de transações (alô, Sagas);
  • versionamento de contratos entre serviços e múltiplos pipelines de CI/CD;
  • uma camada extra de observabilidade e infraestrutura só para você conseguir enxergar o que está acontecendo.

E aqui está o ponto que eu acho mais importante e que raramente é dito em voz alta: se as fronteiras de negócio ainda não estão claras, distribuir o sistema cedo não organiza nada. Só transforma uma bagunça centralizada em várias bagunças conversando entre si pela rede — só que agora essa bagunça tem latência, tem falha de rede e é dez vezes mais difícil de debugar.
 

Então o que é, na prática, um Monolito Modular?

Esquece a ideia de monolito como "aquele código gigante e emaranhado que ninguém quer tocar". Isso é só um monolito mal feito — o que, aliás, também existe em versão distribuída, e nesse caso é ainda pior.

Um Monolito Modular é uma única unidade de deploy, sim. Mas por dentro, ele tem fronteiras internas fortes e propositais. Do ponto de vista de infraestrutura, é um sistema só. Do ponto de vista de código, são vários módulos de negócio bem separados, cada um cuidando da sua própria fatia do domínio.

Pensa numa plataforma de telemedicina, por exemplo. Os módulos poderiam ser algo como:

  • Identidade — autenticação e controle de acesso;
  • Perfis — dados de pacientes, médicos e afins;
  • Agendamento — marcação de consultas;
  • Atendimento — a sessão clínica em si;
  • Pagamentos — faturamento e cobrança;
  • Notificações — lembretes e alertas.

Cada módulo tem sua própria lógica, seu próprio modelo de domínio, suas próprias regras de consistência. Ele não sabe (e não precisa saber) como o módulo vizinho resolve os problemas dele.

A ideia central, resumida numa frase: uma única unidade de deploy não é sinônimo de uma bagunça única de código.
 

Por que isso costuma ser o melhor ponto de partida

O Monolito Modular entrega boa parte do que os times realmente querem quando falam em microsserviços — sem cobrar o pedágio da distribuição precoce:

  • fronteiras e responsabilidades bem definidas dentro do próprio código;
  • separação limpa entre os conceitos de negócio;
  • ambiente local rápido de rodar, depurar e testar (sem precisar subir dez containers só pra ver uma tela);
  • deploy simples e transações que continuam sendo... transações de verdade, sem coreografia distribuída;
  • custo operacional muito mais baixo.

E o ganho mais subestimado de todos: o time consegue focar em entender o domínio, refinar modelos e ajustar fronteiras de negócio antes de precisar pagar a conta cara da complexidade distribuída. Isso é tempo e energia que, numa arquitetura já fragmentada em serviços, teriam sido queimados resolvendo problema de infraestrutura em vez de problema de negócio.

A maturidade da arquitetura nasce dentro do próprio código

Aqui vai uma provocação que gosto de fazer sempre que esse assunto surge: se um time não consegue manter fronteiras limpas dentro de um único repositório, é bem pouco provável que ele vá conseguir manter essas mesmas fronteiras limpas espalhadas entre vários serviços distribuídos.

Microsserviços não criam boa arquitetura por conta própria. Eles só escancaram se você já tinha uma ou não.

E o Monolito Modular acomoda muito bem os conceitos que times já usam (ou deveriam usar) no dia a dia:

  • Bounded Contexts ganham um lar concreto dentro da estrutura de módulos;
  • Agregados protegem suas próprias invariantes e regras dentro de cada módulo;
  • Domain Events permitem que módulos reajam a acontecimentos relevantes sem se acoplar diretamente uns aos outros;
  • Commands e Queries deixam cada módulo com a escrita separada da leitura, de forma organizada.
     

Refatorar fica mais barato quando o negócio ainda está mudando

No começo de qualquer projeto, requisito muda, premissa cai por terra, termo de negócio ganha um significado novo na semana seguinte. Isso é normal — é o processo de descoberta acontecendo.

Num Monolito Modular, lidar com essa instabilidade é relativamente indolor: você move responsabilidade de um módulo pra outro, ajusta um fluxo, renomeia um conceito, e pronto. Sem precisar coordenar versionamento de contrato de API entre serviços, sem sincronizar múltiplos deploys, sem quebrar consumidores externos por engano.

E vale reforçar uma coisa: o inimigo real do software nunca foi "o monolito" em si. É a Grande Bola de Lama — aquele emaranhado sem fronteira nenhuma. E essa bola de lama acontece tanto num monolito mal cuidado quanto numa arquitetura de microsserviços mal desenhada. Trocar de estilo arquitetural não resolve desorganização; só muda o formato dela.
 

E quando os microsserviços realmente valem a pena?

Não estou aqui defendendo que microsserviços são um erro — longe disso. Eles fazem muito sentido quando existe uma razão concreta para arcar com o custo que eles trazem:

  • necessidade real de escalar áreas específicas de forma independente;
  • ritmos de deploy genuinamente diferentes entre partes do sistema;
  • times grandes que precisam de autonomia real sobre suas próprias fronteiras;
  • exigências regulatórias fortes, como isolamento de dados sensíveis de pagamento;
  • maturidade operacional já comprovada pra sustentar sistemas distribuídos no dia a dia.

E aqui está a parte que eu acho mais elegante de tudo isso: manter uma boa modularidade interna não te tranca no monolito. Pelo contrário — com módulos bem definidos, extrair um serviço no futuro vira um processo natural, quase mecânico. Você não está fazendo uma reescrita traumática do zero; está apenas movendo uma fronteira que já existia para fora do processo.
 

Os erros mais comuns na hora de montar um Monolito Modular

Dois erros aparecem com uma frequência impressionante:

1. Organizar por camada técnica, não por capacidade de negócio. Juntar todos os controllers numa pasta, todos os services em outra, todos os repositories em outra — isso cria camadas, não módulos. O resultado é um monolito onde tudo depende de tudo, porque não existe fronteira de negócio nenhuma, só fronteira técnica. A estrutura precisa girar em torno dos módulos de negócio (Agendamento, Pagamentos, Atendimento), não em torno de padrões técnicos genéricos.

2. Dar um jeitinho e furar a fronteira entre módulos. Acessar direto a tabela de outro módulo "porque é mais rápido", ou compartilhar uma entidade transacional entre dois contextos diferentes — isso destrói a fronteira que você acabou de criar. A comunicação entre módulos precisa ser intencional: via interface pública, via evento, nunca por atalho.

Resumo pra quem só quer a resposta rápida

Vá de Monolito Modular quando:

  • o domínio de negócio ainda está sendo descoberto e mudando;
  • o time é pequeno ou médio;
  • simplicidade operacional e velocidade de entrega pesam mais no momento;
  • os fluxos de ponta a ponta ainda são fortemente interligados.

Considere Microsserviços quando:

  • as fronteiras de negócio já estão maduras e bem consolidadas;
  • módulos específicos realmente exigem escala e infraestrutura diferenciadas;
  • a organização já tem estrutura e maturidade pra operar sistemas distribuídos.
     

Pra fechar

Microsserviços não são o ponto de partida de uma arquitetura de backend sólida. Fronteiras bem definidas é que são.

O Monolito Modular te dá espaço pra construir essas fronteiras com bem menos atrito operacional, ciclos de feedback muito mais rápidos e mais liberdade pra aprender sobre o negócio antes de tomar decisões caras e difíceis de desfazer.

Na prática, pra maioria dos sistemas corporativos por aí, a decisão mais madura não é "distribuir logo de cara". É virar modular primeiro — e distribuir só quando (e se) isso realmente fizer sentido.