O padrão strangler fig para migrações legacy

Rewrites big-bang apostam tudo em uma data. O padrão strangler fig vence roteando tráfego endpoint por endpoint — construindo o sistema novo ao redor do antigo até o núcleo legacy ficar oco e seguro de remover.

Engenharia6 min de leitura
Migração legacyStrangler figArquitetura de softwareRefactoringSistemas distribuídos
Compartilhar

O rewrite levava dezoito meses. Chegou a data de lançamento. O tráfego mudou. Três semanas depois, o tráfego voltou. O sistema novo tratava happy paths; edge cases viviam só no codebase legacy que ninguém tinha mapeado por completo. Integrações de folha de pagamento, overrides de admin, códigos promocionais de dez anos — a aposta big-bang de que uma data no calendário podia substituir verdade incremental. Strangler fig legacy migration faz a aposta oposta: rotear uma capacidade por vez, provar cada slice em produção, manter rollback trivial até o sistema antigo não ter mais nada a fazer.

O padrão nomeia uma figueira que cresce ao redor de uma árvore hospedeira, eventualmente substituindo-a. Em software: uma fachada ou router fica na frente do sistema legacy. Novas implementações absorvem endpoints, eventos ou caminhos de dados. O núcleo legacy encolhe até descomissionamento ser um projeto pequeno, não um evento de risco para toda a empresa.

Rewrites big-bang falham em unknown unknowns

Risco big-bangPor que se compõe
Regras de negócio ocultasSó surgem sob edge cases em produção
Desenvolvimento paraleloLegacy continua mudando durante o rewrite
Lacunas no inventário de integraçõesConsumidores não documentados aparecem no cutover
Rollback tudo-ou-nadaReverter é tão arriscado quanto o lançamento
Queda de moralLongos períodos escuros antes da validação

Rewrites parecem limpos em diagramas de arquitetura. São bagunçados em backlogs de tickets, SLAs de parceiros e auditorias de compliance. O strangler fig aceita bagunça de antemão — sistemas duais, complexidade de roteamento, duplicação temporária de dados — em troca de entrega contínua de valor e passos reversíveis.

Uma migração sem rollback por passo é um rewrite disfarçado de plano de projeto.

Anatomia de uma migração strangler fig

Fachada / router. Ponto de entrada único para clientes — API gateway, reverse proxy ou router de aplicação. Todo tráfego passa por ali. Regras de roteamento decidem implementação legacy vs nova por endpoint, feature flag ou tenant.

Seleção de slice. Escolher limites com inputs e outputs claros — um recurso REST, um tipo de evento, um batch job. Não "o módulo de billing" — POST /invoices, evento InvoiceCreated, job noturno de reconciliação.

Nova implementação. Construir atrás da fachada. Modo shadow opcional: sistema novo processa requests mas não responde a clientes — comparar outputs antes do cutover.

Mudança de tráfego. Por porcentagem, por tenant ou cutover completo por slice. Feature flags controlam roteamento sem redeploy da fachada.

Encolhimento do legacy. Remover código roteado do legacy só após prova sustentada — métricas verdes, sem rollback por N dias, reconciliação limpa.

Descomissionamento. Quando legacy trata zero tráfego de produção e não há dependências batch, aposentar infraestrutura.

Clients → Facade/Router
              ├─ /users/*     → New User Service
              ├─ /orders/*    → New Order Service  
              ├─ /reports/*   → Legacy Monolith
              └─ /admin/*     → Legacy Monolith (last)

O artigo sobre arquitetura modular monolith para startups descreve limites internos de módulos que viram slices naturais de strangler — extrair um módulo para serviço sem reescrever a aplicação inteira.

Migração de dados é a parte difícil que roteamento não resolve

Rotear tráfego HTTP é a camada visível. Dados costumam sobreviver ao código.

Padrão de dadosAbordagem strangler
Slice read-heavyNovo serviço lê réplica; legacy ainda escreve até cutover
Migração de escritaPeríodo dual-write — ambos sistemas aceitam escritas, job de reconciliação compara
Sync event-drivenLegacy emite eventos de mudança; sistema novo constrói read model
Anti-padrão de banco compartilhadoExtrair slice de schema para DB nova com sync; último recurso são tabelas compartilhadas com ownership estrito

Períodos dual-write precisam de reconciliação — comparar contagens de linhas, checksums, diffs de amostra em schedule. Divergência descoberta no descomissionamento é cara. Divergência descoberta toda noite é gerenciável.

Nunca deletar caminhos de dados legacy até o caminho novo ter processado tráfego de produção por um ciclo de negócio completo — fechamento de mês, ciclo de billing, janela de reporting de compliance.

Estratégia de ordenação de slices

Nem todo endpoint é candidato igual de migração.

Migrar primeiro:

  • Domínios de alto churn e bem entendidos com boa cobertura de testes
  • Caminhos read-heavy onde escritas legacy defasadas sejam toleráveis brevemente
  • Features bloqueando nova direção de produto
  • Endpoints com poucos consumidores não documentados

Migrar por último:

  • Caminhos de admin e override com regras de negócio implícitas
  • Batch jobs com dependências de calendário
  • Integrações com parceiros externos que exigem recertificação
  • Áreas onde o "como funciona" vive na cabeça de um único engenheiro

Cada slice shipa de forma independente. Celebrar conclusão de slice — não só descomissionamento final. Moral sobrevive a prova incremental.

Operações de fachada: roteamento, observabilidade, rollback

A fachada é infraestrutura de produção. Tratá-la como tal.

  • Config de roteamento como código — regras versionadas, mudanças revisadas, trilha de auditoria.
  • Métricas por rota — latência, taxa de erro, divisão de tráfego legacy vs novo.
  • Rollback instantâneo — virar flag ou regra de roteamento para 100% legacy em um slice sem afetar outros.
  • Rastreamento de requests — correlation ID através da fachada até implementação; essencial para comparação em shadow mode.

Feature flags como infraestrutura de release se sobrepõe ao roteamento strangler — flags controlam qual implementação serve tráfego. A diferença é intenção estratégica: flags compuertam features; flags strangler compuertam substituição arquitetural.

Como equipes devem planejar uma migração strangler fig?

Essas perguntas evitam fachadas que viram complexidade permanente.

Quando strangler fig é melhor que rewrite?

Quando legacy está em produção com usuários reais, regras ocultas e integrações que não podem pausar. Quando o time precisa shipar novas capacidades durante a migração. Quando rollback por slice é requisito. Rewrite pode servir substituição greenfield sem dependência de produção — raro em sistemas maduros.

Quão pequeno deve ser um slice?

Pequeno o bastante para rollback em uma mudança de roteamento. Grande o bastante para entregar valor significativo. Típico: um grupo de recursos API, um consumidor de eventos, um job agendado — semanas a meses, não dias ou anos.

O que impede a fachada de virar permanente?

Rastrear porcentagem de tráfego legacy por rota. Definir critérios de descomissionamento de antemão: "tráfego legacy /orders = 0 por 30 dias." Fachadas sem métricas de sunset viram operação de sistemas duais para sempre.

Um argumento comum vai na direção oposta

A visão oposta sustenta que manter dois sistemas custa mais que um rewrite rápido — que strangler fig prolonga dor e duplica esforço.

Custo de sistemas duais é real e deve ser orçado. Custo de falha big-bang — reverter, meses perdidos, impacto em clientes — é maior e menos previsível. Strangler fig limita downside por slice. O tempo total em calendário pode exceder um big-bang bem-sucedido, mas big-bangs que falham não têm tempo total em calendário — têm um reinício.

Times com capacidade limitada se beneficiam justamente porque slices cabem em sprints normais junto com trabalho de features. Rewrites consomem o roadmap.

Key takeaways

  • Strangler fig migra um endpoint ou capacidade por vez atrás de um router fachada.
  • Rewrites big-bang falham em edge cases e integrações descobertas só no cutover.
  • Dual-write de dados e reconciliação importam tanto quanto roteamento de tráfego.
  • Migrar primeiro slices read-heavy bem entendidos; admin e batch jobs por último.
  • Rollback por slice via flags de roteamento mantém migração reversível.
  • Rastrear tráfego legacy por rota — fachadas sem métricas de sunset viram permanentes.

Conclusion

Migração legacy não é um projeto com linha de chegada em um Gantt. É uma sequência de pequenas provas de que o sistema novo pode carregar verdade de produção — um slice por vez, com o sistema antigo ainda de pé até cada prova se sustentar.

O primeiro passo não é escrever código novo. É inventário: listar cada entry point ao sistema legacy, medir tráfego e risco por rota, escolher o slice de maior valor mais pequeno e colocar um router na frente. A figueira cresce dali.

Artigos relacionados

Paleta de comandos

Pesquise um comando para executar...