Marcio Cunha

Padrão Strangler Fig na Prática: Migrando Monolitos para Microsserviços sem Reescrita Total

Descubra como o padrão Strangler Fig permite modernizar sistemas legados de forma incremental, substituindo funcionalidades antigas por microsserviços modernos sem os riscos de uma reescrita do zero.

Marcio Cunha12 min
Também disponível em:EnglishEspañol
Resumo
  • A reescrita total de sistemas legados costuma falhar por ignorar regras de negócio implícitas e acumular atrasos crônicos.
  • O padrão Strangler Fig cria uma fachada de roteamento para interceptar requisições e redirecioná-las gradualmente para o novo código.
  • A divisão de domínios via Domain-Driven Design ajuda a identificar quais partes do monolito devem ser isoladas primeiro.
  • O uso de bancos de dados compartilhados no início da migração reduz a complexidade, embora exija cautela para evitar dependências duradouras.
  • A observabilidade rigorosa e feature flags garantem que falhas no novo serviço sejam revertidas rapidamente sem impacto para o usuário.

O Dilema do Monolito Legado e o Risco da Reescrita Total

Quase toda empresa que cresce passa pelo mesmo problema: o sistema que deu certo no início vira um monolito complexo, um emaranhado de código onde ninguém ousa mexer por medo de que tudo pare de funcionar. O impulso natural da equipe de engenharia é jogar tudo fora e reescrever o software do zero. Na prática, isso significa prometer um prazo que nunca é cumprido, ignorar anos de regras de negócio escondidas em cantos esquecidos do código e entregar um produto novo que sofre dos mesmos problemas do antigo. A reescrita total é um dos maiores sumidouros de orçamento e tempo na indústria de software.

Para fugir dessa armadilha, a engenharia de software adotou uma estratégia inspirada na natureza: o padrão Strangler Fig, ou padrão da figueira estranguladora. Na floresta tropical, a semente dessa planta germina no topo de uma árvore hospedeira, enviando raízes para o solo. Com o tempo, a figueira cresce ao redor da árvore original, sufocando-a lentamente até que a hospedeira morra e sobre apenas a nova árvore, oca por dentro mas estruturalmente firme. No desenvolvimento de software, a ideia é exatamente a mesma: construir um sistema novo ao redor do antigo, substituindo pedaços aos poucos até que o legado desapareça por completo.

Como Funciona a Arquitetura de Interceptação de Tráfego

O coração do padrão Strangler Fig é um mecanismo de roteamento, geralmente implementado por meio de um proxy reverso ou API Gateway, que é um ponto único de entrada para todas as requisições do sistema. Na prática, este componente atua como um porteiro inteligente na entrada de um prédio comercial, olhando para o crachá de cada visitante e decidindo se ele deve ser encaminhado para as salas antigas ou para a ala nova e reformada. Quando um usuário clica em um botão na tela, a requisição passa por esse roteador central, que sabe exatamente quais rotas já foram migradas para os novos microsserviços e quais ainda dependem do monolito.

Para implementar essa lógica, os engenheiros configuram regras de redirecionamento baseadas em caminhos de URL ou cabeçalhos HTTP. Por exemplo, todas as chamadas direcionadas para /api/v1/users continuam indo para o monolito legado, enquanto o caminho /api/v2/users é direcionado para o novo microsserviço de usuários construído com tecnologias modernas. Esse desacoplamento permite que a transição ocorra de forma totalmente transparente para o cliente final, seja ele um aplicativo móvel ou um navegador web, garantindo estabilidade operacional contínua durante todo o processo de modernização.

Isolando Domínios e Definindo Fronteiras com Domain-Driven Design

O maior erro ao iniciar uma migração Strangler Fig é tentar fatiar o monolito aleatoriamente por arquivos ou funções. É preciso usar Domain-Driven Design, uma abordagem de projeto que alinha o desenvolvimento de software aos conceitos e processos reais do negócio. Na prática, isso significa mapear os limites naturais da empresa — como faturamento, gestão de estoque ou cadastro de clientes — e tratar cada um deles como um domínio isolado. Identificar o primeiro domínio a ser extraído exige avaliar qual parte do sistema sofre mais alterações frequentes ou apresenta gargalos de performance mais críticos.

Um bom candidato inicial costuma ser uma funcionalidade periférica e autônoma, com poucas dependências cruzadas com o resto do sistema, como o serviço de envio de e-mails ou a emissão de relatórios mensais. Ao escolher uma parte isolada, a equipe ganha confiança no processo de deploy e valida a infraestrutura de microsserviços sem colocar em risco o núcleo financeiro da aplicação. Esse sucesso inicial reduz a resistência interna à mudança e fornece métricas reais sobre o esforço necessário para as próximas etapas da migração.

Gerenciamento de Dados e Estratégias de Transição de Banco

O maior desafio técnico em qualquer migração de monolito não é mover o código, mas sim lidar com os dados. Em um monolito tradicional, dezenas de módulos diferentes leem e escrevem nas mesmas tabelas de um banco de dados relacional centralizado, criando um acoplamento invisível mas extremamente rígido. Quando extraímos um microsserviço, a regra de ouro é que ele deve possuir seu próprio banco de dados independente, garantindo autonomia total. No entanto, quebrar esse banco central de uma só vez é inviável, pois as funcionalidades legadas ainda dependem das mesmas informações.

Para resolver esse dilema, utiliza-se uma fase de transição onde o novo microsserviço lê e escreve no banco de dados legado, ou emprega-se um padrão de replicação de dados em tempo real utilizando ferramentas de streaming de eventos como o Apache Kafka. Outra estratégia comum é o uso da técnica de escrita dupla, onde a aplicação atualizada grava os dados simultaneamente no banco antigo e no novo até que a migração esteja madura o suficiente para desligar o armazenamento legado. Esse cuidado evita perdas de dados e garante consistência durante o período em que o sistema antigo e o novo convivem no mesmo ambiente de produção.

// Exemplo conceitual de proxy reverso em Node.js para roteamento Strangler Fig
const http = require('http');
const httpProxy = require('http-proxy');

const proxy = httpProxy.createProxyServer({});

const server = http.createServer((req, res) => {
  // Roteia novas rotas para o microsserviço e o restante para o monolito legado
  if (req.url.startsWith('/api/v2/catalog')) {
    proxy.web(req, res, { target: 'http://localhost:4000' });
  } else {
    proxy.web(req, res, { target: 'http://localhost:3000' });
  }
});

server.listen(8080, () => {
  console.log('API Gateway Strangler operando na porta 8080');
});

Monitoramento, Feature Flags e Mitigação de Riscos

Substituir partes de um sistema em produção é como fazer uma cirurgia de coração aberto com o paciente acordado: exige precisão milimétrica e capacidade de resposta imediata a qualquer sinal de falha. Para manter o controle, as equipes utilizam feature flags, que são chaves configuráveis no código que permitem ligar ou desligar novas funcionalidades remotamente sem precisar fazer um novo deploy. Na prática, se o microsserviço recém-criado começar a apresentar erros de timeout, o operador pode desativar a chave de roteamento e devolver instantaneamente o tráfego para o monolito legado em segundos.

Além disso, a observabilidade baseada em métricas, logs centralizados e rastreamento distribuído torna-se obrigatória. Ferramentas de APM (Application Performance Monitoring) permitem comparar a latência e a taxa de erro entre o código antigo e o novo em tempo real. Com esses dados em mãos, a engenharia pode validar se a migração está trazendo os ganhos de performance esperados ou se há gargalos ocultos na rede entre os novos microsserviços. O sucesso de uma estratégia Strangler Fig mede-se não pela velocidade com que o monolito é destruído, mas pela suavidade com que a transição acontece para os usuários.

Conclusão e Considerações Finais sobre Modernização Incremental

A modernização de sistemas legados através do padrão Strangler Fig prova que a evolução arquitetural não precisa ser um salto no escuro. Ao dividir o problema em fatias menores e substituir o código de forma controlada e incremental, as organizações evitam os riscos catastróficos das reescritas totais e entregam valor contínuo ao negócio sem interromper a operação. Essa abordagem transforma o débito técnico acumulado ao longo de anos em um plano de ação gerenciável e sustentável.

Em última análise, o sucesso dessa jornada depende tanto da disciplina técnica quanto da mudança cultural na equipe de engenharia. Aceitar que o sistema antigo e o novo vão conviver por meses — ou até anos — exige paciência e rigor na governança das APIs e na gestão de dados. Quando bem executado, o padrão Strangler Fig não apenas substitui código velho por tecnologia moderna, mas também capacita a equipe a entregar software com mais agilidade, resiliência e confiança para o futuro.