13 de Junho de 2025
Como Migrar um Serviço Antigo Sem Reescrever Tudo de Uma Vez
Como sair de um serviço herdado para algo melhor sem apostar tudo em um big bang que você não controla.
Andrews Ribeiro
Founder & Engineer
4 min Intermediario Sistemas
O problema
Serviço antigo costuma gerar a mesma fantasia em quase todo time:
“Ninguém entende isso direito. Vamos reescrever e pronto.”
O impulso e compreensivel.
O problema e que reescrita total costuma trocar um sistema feio, mas conhecido, por um sistema bonito, porem cheio de comportamento ainda não descoberto.
Em migração, o risco maior raramente e o código velho.
Quase sempre e isto:
- regra escondida que ninguém documentou
- dependência operacional esquecida
- consumidor que ainda depende do comportamento antigo
- rollback inexistente quando a parte nova falha
Modelo mental
Pense assim:
migrar serviço antigo e reduzir dependência no legado sem perder comportamento que o negócio ainda precisa
Isso muda o foco.
O alvo não e “reescrever tudo”.
O alvo e:
- entender o que o serviço realmente faz
- separar uma fronteira pequena
- mover essa fronteira com observabilidade
- repetir sem ampliar demais o risco por vez
Migração boa costuma parecer menos heroica e mais disciplinada.
Quebrando o problema
Descubra o comportamento real antes de prometer arquitetura nova
Serviço antigo quase sempre faz mais do que parece.
Não basta olhar o repositorio e listar endpoints.
Você precisa descobrir:
- quem chama
- quais side effects existem
- que formato de dado entra e sai
- quais jobs, filas ou webhooks também dependem dele
- que comportamento estranho virou contrato na prática
Sem isso, a migração vira teatro técnico.
Escolha uma fatia pequena e defendavel
O pior recorte e “vamos migrar o serviço inteiro”.
O melhor costuma ser algo mais específico:
- um endpoint
- um caso de uso
- um tenant
- um tipo de evento
- uma parte do fluxo de escrita ou leitura
Fronteira boa e aquela que permite mover valor sem mover o planeta junto.
Separe roteamento de implementação
Se velho e novo vao conviver, alguém precisa decidir para onde cada chamada vai.
Esse ponto pode estar em:
- gateway
- facade interna
- fila
- feature flag
- configuração por tenant ou cohort
O importante e não acoplar a decisão de roteamento ao deploy como se tudo mudasse junto.
Migre com observabilidade e critério de parada
Migração sem medição e só fe.
Você precisa enxergar:
- volume de tráfego indo para cada lado
- erro e latência do fluxo novo
- divergencia de resultado entre velho e novo
- dependência que ainda impede desligar o antigo
E também precisa saber quando parar.
Se erro sobe, se resultado diverge, se suporte começa a receber sinal ruim, a migração precisa congelar sem drama.
Desligue o velho só quando ele realmente parou de ser necessário
Serviço antigo não morre quando a branch nova entrou.
Ele morre quando:
- não recebe mais tráfego relevante
- não sustenta mais fallback
- não serve mais como rollback
- nenhuma dependência esquecida aponta para ele
Antes disso, remover cedo demais só troca ansiedade por incidente.
Exemplo simples
Imagine um serviço antigo de cobrança que:
- calcula desconto
- gera boleto
- notifica cliente
- escreve em mais de um banco
O time quer “migrar cobrança”.
Esse plano e ruim porque e grande demais.
Um plano melhor seria:
- mapear o fluxo de emissao de boleto separadamente
- criar um caminho novo só para esse caso de uso
- mandar primeiro tráfego interno ou de poucos clientes para o novo fluxo
- comparar erro, tempo e resultado
- ampliar aos poucos
- só depois pegar outra parte, como notificação ou calculo de desconto
Não ficou elegante em slide.
Ficou controlavel em produção.
Erros comuns
- Tratar desconhecimento como justificativa para reescrever tudo.
- Escolher um recorte grande demais para a primeira migração.
- Mover implementação sem saber quem depende do comportamento antigo.
- Fazer o novo fluxo sem medição de divergencia.
- Deixar o legado vivo sem plano de aposentadoria, criando duplicação eterna.
Como um senior pensa
Quem tem mais experiência costuma fazer perguntas menos glamourosas e mais uteis:
“Qual a menor parte que consigo mover agora sem perder rollback nem visibilidade?”
Essa pergunta geralmente vale mais do que discutir nome de padrão.
Senioridade aqui aparece em duas coisas:
- conter escopo da migração
- proteger o negócio enquanto a mudança acontece
O que o entrevistador quer ver
Em entrevista, esse tema mede maturidade de execução.
O avaliador quer ver se você:
- evita big bang por padrão
- pensa em fronteira incremental
- considera compatibilidade e roteamento
- fala de observabilidade e rollback junto com a mudança
Uma resposta forte costuma soar assim:
“Eu não tentaria trocar o serviço inteiro de uma vez. Primeiro mapearia comportamento real, escolheria uma fatia pequena, criaria um mecanismo de roteamento gradual, mediria divergencia e só ampliaria quando o novo fluxo estivesse confiavel.”
Migrar bem e mais sobre controlar desconhecidos do que sobre escrever serviço novo.
Reescrita total costuma parecer coragem. Muitas vezes e só risco mal embalado.
Resumo rápido
O que vale manter na cabeça
- Migração segura quase nunca acontece como troca unica; ela acontece como redução progressiva de risco.
- Antes de mover código, você precisa entender comportamento, dependência e efeito colateral do serviço antigo.
- A fronteira certa para migrar costuma ser um fluxo pequeno e observável, não o serviço inteiro de uma vez.
- Rollback e compatibilidade precisam existir desde o início, não aparecer no fim como remedio.
Checklist de pratica
Use isto ao responder
- Consigo explicar por que reescrita total costuma esconder mais risco do que remove?
- Sei descrever como escolher uma fatia pequena para migrar primeiro?
- Consigo falar de observabilidade, roteamento gradual e rollback na mesma resposta?
- Sei responder em entrevista como desmontaria um serviço antigo sem depender de corte perfeito?
Você concluiu este artigo
Compartilhar esta página
Copie o link manualmente no campo abaixo.