Repositório não é arquitetura: separar frontend e backend não é microserviço
Dividir o código em dois repositórios é uma decisão de logística. Monólito e microserviços são decisões de runtime. Confundir as duas coisas é o erro mais repetido nos grupos de tecnologia — e sai caro.
Toda semana aparece a mesma thread em algum grupo de Facebook, Discord ou Telegram de programação: "aqui na empresa a gente migrou pra microserviços — separamos o repositório do front do repositório da API". Não migrou. Você tem o mesmo sistema de antes, com um git remote a mais.
O mito e suas três variações
O erro nunca aparece exatamente igual, mas sempre com a mesma raiz — usar a contagem de repositórios como proxy para maturidade arquitetural. As três versões mais comuns:
“Separei o front do back, agora é microserviço.” Não. Você separou duas camadas técnicas de uma mesma aplicação. Isso é arquitetura cliente-servidor, algo que já existia antes de a palavra “microserviço” ser cunhada.
“Está tudo num repositório só, então é monólito.” Também não. Google, Meta e Uber rodam milhares de serviços independentes a partir de um único repositório. O monorepo é sobre onde o código mora, não sobre o que roda em produção.
“Temos 12 repositórios, temos arquitetura distribuída madura.” Talvez. Ou talvez você tenha 12 repositórios que precisam subir juntos, na mesma janela de deploy, contra o mesmo banco de dados. Isso tem nome, e não é elogio: monólito distribuído.
Dois eixos, quatro quadrantes
A maneira mais rápida de matar a discussão é desenhar a matriz. Repositórios em um eixo, unidades de deploy no outro:
| Cenário | Repositórios | Unidades de deploy | É microserviço? |
|---|---|---|---|
| Laravel/Rails servindo HTML, tudo junto | 1 | 1 | ✗ |
| SPA em React + API .NET, um repo cada | 2 | 2 | ✗ |
| 40 serviços de domínio dentro de um monorepo | 1 | 40 | ✓ |
| 12 repositórios que sobem no mesmo release coordenado | 12 | 1 (na prática) | ✗ |
| 8 serviços, 8 repos, 8 bancos, deploy independente | 8 | 8 | ✓ |
Repare que a coluna de repositórios não prevê a última coluna em nenhuma linha. Ela simplesmente não carrega essa informação.
O mesmo sistema, exatamente com a mesma arquitetura de runtime, pode ser guardado dos dois jeitos:
# Layout A — monorepo
plataforma/
├── services/
│ ├── catalog/ → container próprio, banco próprio, deploy próprio
│ ├── checkout/ → container próprio, banco próprio, deploy próprio
│ └── notifications/ → container próprio, banco próprio, deploy próprio
├── web/ → bundle estático servido por CDN
└── libs/contracts/ → contratos compartilhados
# Layout B — polirepo
org/service-catalog → container próprio, banco próprio, deploy próprio
org/service-checkout → container próprio, banco próprio, deploy próprio
org/service-notifications → container próprio, banco próprio, deploy próprio
org/web-app → bundle estático servido por CDN
org/contracts → pacote versionado no registry
Em produção, A e B são indistinguíveis. Mesmos containers, mesmos bancos, mesma malha de rede, mesmos SLAs. A diferença está inteiramente no fluxo de trabalho da equipe: como se abre PR, como roda CI, quem tem permissão de escrita, como se faz um refactor que cruza fronteiras.
O que define um monólito de verdade
Monólito não é sinônimo de código ruim, legado ou bagunçado. A definição é técnica e bem chata:
JOIN resolvendo qualquer consulta.Note que nada disso menciona repositórios. Um monólito pode estar espalhado por vinte repositórios que são montados no build — continua sendo monólito, porque o que chega em produção é um artefato só.
O que define microserviços
A definição de Lewis e Fowler é bem específica: um conjunto de serviços pequenos, cada um rodando no próprio processo, comunicando-se por mecanismos leves, construídos em torno de capacidades de negócio e implantáveis de forma independente por maquinário automatizado.
A parte que a galera dos grupos pula é justamente a mais importante — “capacidades de negócio” e “implantáveis de forma independente”. Um checklist honesto:
Se você riscou menos de quatro desses seis itens, o que você tem é um sistema distribuído — o que é bem diferente de ter microserviços, e traz todo o custo sem boa parte do benefício.
Frontend e backend separados são camadas, não serviços
Aqui está o coração do mal-entendido. Quando você separa web-app de api, você não decompôs o domínio: você separou a apresentação da regra de negócio. Isso é uma fronteira técnica, e ela já existia mesmo quando os dois moravam na mesma pasta — o navegador sempre foi um processo separado do servidor.
Pior: o frontend de uma SPA normalmente nem é um serviço. É um monte de arquivo estático num bucket, servido por CDN. Ele não tem banco, não tem estado do lado do servidor, não escala independentemente de nada relevante. Chamar isso de “um dos nossos microserviços” é chamar o cardápio de filial do restaurante.
E não: a API monolítica de 400 mil linhas atrás daquela SPA não fica menos monolítica porque o React saiu de dentro dela. Ela continua sendo um único deployable, com um único banco e um único ciclo de release. Você só trocou uma chamada de renderização por uma chamada HTTP.
Existe, sim, uma versão legítima disso — micro-frontends —, mas o critério é o mesmo de sempre: pedaços da interface implantáveis de forma independente, cada um alinhado a um domínio de negócio, cada um com seu time. Front separado do back não é micro-frontend, do mesmo jeito que não é microserviço.
O teste das cinco perguntas
Da próxima vez que aparecer a discussão, ignore o diagrama e faça estas perguntas. Elas levam menos de cinco minutos e não deixam espaço para retórica:
- Consigo colocar o serviço A em produção hoje sem tocar em nenhum outro repositório?
- Se A cair às 3h da manhã, B continua respondendo — nem que seja degradado?
- A e B têm bancos separados, e ninguém faz consulta cruzada direto no schema do vizinho?
- Consigo subir a versão do framework em A sem abrir um chamado para outro time?
- Existe um time que decide sozinho quando A vai para produção?
Cinco “sim”: microserviços. Alguns “não”: sistema distribuído em transição, o que é uma resposta perfeitamente respeitável. Cinco “não” com doze repositórios: monólito distribuído, e vale conversar sobre isso antes que doa mais.
Repare que a pergunta “quantos repositórios vocês têm?” não aparece na lista. Ela não é diagnóstica.
Monólito distribuído: o pior dos dois mundos
Esse é o destino de quem confunde os dois eixos e “migra para microserviços” fatiando repositórios. Os sintomas são fáceis de reconhecer:
| Sintoma | O que ele revela |
|---|---|
| Adicionar um campo exige PR em cinco repositórios | Os serviços compartilham modelo, não contrato |
| Existe uma "janela de release" com todos os times | Não há deploy independente |
| Um serviço fora do ar derruba o checkout inteiro | Não há isolamento de falha |
| Todos os serviços apontam para o mesmo banco | Não há propriedade de dados |
| Rollback de um serviço obriga rollback dos outros | Os contratos não são versionados |
Nesse cenário, você pagou toda a fatura da arquitetura distribuída — latência de rede, falhas parciais, consistência eventual, observabilidade, service discovery, complexidade de testes de integração — e recebeu de volta exatamente zero autonomia. É estritamente pior do que o monólito bem organizado que existia antes.
A Segment documentou publicamente esse caminho: fatiaram o sistema em mais de cem serviços, viram o custo operacional explodir e voltaram para um monólito. Não porque microserviços sejam ruins, mas porque o recorte não correspondia a fronteiras reais de time e de domínio.
Monólito modular: o meio-termo que ninguém posta no grupo
Entre “tudo embolado” e “cem serviços” existe uma opção que resolve a maioria dos problemas reais: manter uma única unidade de deploy, mas com fronteiras internas explícitas e respeitadas — módulos com API pública definida, dependências declaradas, acesso a dados restrito ao próprio módulo.
Foi o caminho da Shopify com uma das maiores bases Rails do mundo: manter o código num único codebase, mas com limites definidos e aplicados entre componentes. Você ganha a clareza de fronteiras sem pagar a conta da rede, e — o detalhe que mais importa — se um módulo realmente precisar virar serviço depois, a fronteira já está desenhada e testada.
Então, quando separar repositórios?
A pergunta certa não é “monólito ou microserviço?”, e sim “qual fronteira de trabalho eu quero tornar cara?”. Separar repositórios encarece mudanças que cruzam a fronteira e barateia autonomia dentro dela.
| Critério | Monorepo | Polirepo |
|---|---|---|
| Mudança atômica cruzando fronteiras | ✓ um PR | ✗ vários PRs coordenados |
| Refactor em larga escala | ✓ busca e substitui | ✗ migração versionada |
| Permissão granular por time | ~ via CODEOWNERS | ✓ nativo |
| CI simples e rápido sem tooling extra | ✗ precisa de build seletivo | ✓ trivial |
| Versionamento independente de artefatos | ~ exige convenção | ✓ natural |
| Descoberta de código e reuso | ✓ tudo visível | ~ depende de registry |
| Contrato entre partes fica explícito | ~ fácil de burlar | ✓ a rede força |
A heurística que uso: separe repositórios por fronteira de propriedade e permissão, não por camada técnica. Se o mesmo time de quatro pessoas cuida do front e do back do mesmo produto, dois repositórios só significam que toda mudança de contrato virou dois PRs, dois reviews e uma janela onde as versões estão fora de sincronia. Se são times diferentes, em fusos diferentes, com ciclos diferentes, a separação paga a si mesma.
O Google mantém a esmagadora maioria do próprio código num repositório único com bilhões de linhas — e roda milhares de serviços independentes a partir dele. É a prova por contradição mais eficiente que existe: se repositório definisse arquitetura, o Google seria o maior monólito do planeta.
Nos últimos anos trabalhei em três empresas fora do Brasil, em domínios bem diferentes: moda de luxo, delivery e seguros. Passei por monorepo com dezenas de serviços dentro e por polirepo com dezenas de repositórios, e a conclusão foi a mesma nos dois casos: o layout do repositório nunca foi o que determinou se dava pra entregar rápido.
O que determinou foi sempre a resposta a uma pergunta só — eu consigo subir minha mudança em produção sem depender do calendário de outro time? Onde a resposta era sim, o dia era bom, independentemente de o código estar em um repositório ou em trinta. Onde era não, a quantidade de repositórios só mudava quantos PRs eu precisava abrir para o mesmo bloqueio.
E vi o monólito distribuído de perto: adicionar um campo em um payload exigia coordenar mudanças em vários repositórios, com uma ordem obrigatória de deploy e uma janela combinada. No papel, era arquitetura de microserviços. Na prática, era um monólito com latência de rede embutida.
O resumo para colar no grupo
Repositório é logística: define como o código é guardado, versionado e revisado. Arquitetura é runtime: define o que sobe em produção, em quantas peças, com quantos ciclos de vida independentes. Um não determina o outro em nenhuma direção.
Separar frontend de backend é uma decisão de organização de trabalho, com prós e contras reais — e nenhum deles é "virar microserviço". Você não decompôs o domínio, decompôs a camada de apresentação. É útil, é comum, é frequentemente a escolha certa. Só não é o que a palavra significa.
E, sinceramente, na maior parte dos projetos que aparecem nesses grupos, a resposta certa é um monólito modular bem desenhado, com um repositório, um deploy e fronteiras internas levadas a sério. Isso não rende post viral, mas rende sistema que sobe na sexta-feira sem ninguém prender a respiração.
Referências
- Lewis, J.; Fowler, M. Microservices: a definition of this new architectural term. martinfowler.com
- Fowler, M. MicroservicePremium. martinfowler.com
- Fowler, M. MonolithFirst. martinfowler.com
- Potvin, R.; Levenberg, J. Why Google Stores Billions of Lines of Code in a Single Repository. Communications of the ACM, v. 59, n. 7, 2016. research.google
- Westeinde, K. Deconstructing the Monolith: Designing Software that Maximizes Developer Productivity. Shopify Engineering. shopify.engineering
- Segment Engineering. Goodbye Microservices: From 100s of problem children to 1 superstar. twilio.com
- Newman, S. Building Microservices: Designing Fine-Grained Systems. 2. ed. O'Reilly Media, 2021. oreilly.com
Categorias