28 de Fevereiro de 2025
Contratos entre serviços e compatibilidade retroativa
Como evoluir integrações internas sem tratar consumidor de outro time como se fosse detalhe do seu deploy.
Andrews Ribeiro
Founder & Engineer
4 min Intermediario Sistemas
O problema
Tem time que trata integração interna como se fosse conversa privada.
Algo como:
“Se eu mudar aqui e quebrar, o outro time ajusta rápido.”
No papel parece eficiente.
Na prática, isso cria o clássico sistema em que todo deploy tem chance de vazar problema para outro serviço.
O motivo e simples:
- um serviço publica comportamento
- outro serviço passa a depender dele
Nesse momento nasceu um contrato.
Mesmo que ninguém tenha dado esse nome.
Modelo mental
Contrato entre serviços e o acordo real entre produtor e consumidor.
Esse acordo inclui:
- campos
- tipos
- obrigatoriedade
- semântica
- status codes
- ordem ou formato de eventos
- regras de erro
Compatibilidade retroativa significa conseguir evoluir esse acordo sem quebrar quem ainda depende da forma anterior.
Em linguagem simples:
o serviço novo continua entendivel para o consumidor antigo.
Quebrando o problema
Schema e só uma parte
Muita conversa sobre contrato para no schema cedo demais.
Mas contrato não e só isto:
{
"id": "123",
"status": "paid"
}
Também e expectativa como:
statussempre vem?- pode vir valor novo?
404significa não existe ou não pode ver?- evento pode chegar duplicado?
Se a resposta para isso não está clara, o contrato continua fraco mesmo com schema “bonito”.
O que costuma ser compativel
Mudancas que frequentemente sao seguras:
- adicionar campo opcional
- aceitar valor novo sem invalidar os antigos
- adicionar endpoint ou evento novo
- enriquecer resposta sem mudar significado anterior
Elas tendem a funcionar porque consumidor antigo continua entendendo o que já sabia.
O que costuma quebrar
Mudancas perigosas:
- remover campo usado por consumidor
- renomear campo
- trocar tipo
- tornar obrigatorio algo que antes não era
- mudar significado de valor existente
- mudar comportamento de erro sem transição
O problema quase nunca e a linha de código.
E a expectativa quebrada do outro lado.
Produtor forte pensa em convivencia
Quando uma mudança importante vem, o produtor maduro pensa em transição:
- adicionar novo campo ou comportamento
- manter o antigo por um tempo
- comunicar depreciação
- medir quem ainda depende
- remover só depois da migração
Isso vale para API HTTP, eventos e integrações por fila.
Consumidor forte também se protege
Compatibilidade não e responsabilidade só do produtor.
Consumidor forte evita assumir demais:
- ignora campos extras
- tolera ausencia de ordem acidental quando o contrato não promete ordem
- não acopla parse a detalhe inutil
- trata valor desconhecido com degradação segura quando faz sentido
Se o consumidor quebra porque apareceu um campo extra, ele também esta fragil.
Exemplo simples
Imagine um serviço de pedidos que responde:
{
"id": "ord_1",
"status": "paid",
"total": 150
}
Outro serviço usa isso para emitir nota fiscal.
Agora o time do produtor quer internacionalizar e muda total para:
{
"total": {
"amount": 150,
"currency": "BRL"
}
}
Para o produtor parece evolução.
Para o consumidor antigo, pode ser quebra direta.
Uma transição melhor seria:
- manter
total - adicionar
amountecurrencyou um novo objeto em paralelo - observar consumo
- remover depois com janela combinada
O ponto forte não e “ficar com legado para sempre”.
E trocar ruptura silenciosa por evolução controlada.
Erros comuns
- Chamar de “interno” e usar isso como desculpa para quebrar contrato.
- Achar que schema valido sozinho garante compatibilidade.
- Mudar semântica mantendo o mesmo nome de campo.
- Tirar campo antigo assim que o consumidor novo fica pronto.
- Não medir quem ainda depende da forma anterior.
Como um senior pensa
Quem tem mais experiência trata integração entre serviços como fronteira de produto, mesmo dentro da empresa.
O raciocínio costuma ser:
“Esse outro serviço e meu cliente operacional. Se eu mudo o acordo sem transição, eu exporto risco para ele.”
Esse jeito de pensar reduz acoplamento humano e técnico ao mesmo tempo.
Menos guerra de deploy. Mais previsibilidade.
O que o entrevistador quer ver
Em entrevista, esse assunto aparece quando pedem evolução de API, eventos ou integrações internas.
O avaliador quer ver se você entende que contrato e compromisso real.
Você sobe de nivel quando:
- diferencia schema de semântica
- fala de transição e depreciação
- menciona observabilidade de consumo
- mostra que consumidor também precisa ser robusto
Uma resposta forte costuma soar assim:
“Eu trataria o contrato entre serviços como acordo estavel. Primeiro tento evolução compativel. Se a mudança for breaking, faco convivencia temporária, meco consumo e removo depois.”
Sistema acoplado demais não falha porque os times são ruins. Falha porque o contrato foi tratado como detalhe.
Resumo rápido
O que vale manter na cabeça
- Contrato não e só nome de campo. E formato, semântica, obrigatoriedade e comportamento esperado.
- Compatibilidade retroativa reduz acoplamento operacional entre produtor e consumidor.
- Mudança pequena para um serviço pode ser breaking para outro se o acordo for implícito.
- Evolução segura depende de adicionar antes de remover, observar consumo e fazer transição explicita.
Checklist de pratica
Use isto ao responder
- Consigo explicar o que faz uma mudança virar breaking para outro serviço?
- Sei diferenciar schema valido de contrato realmente compativel?
- Consigo descrever uma estratégia de transição entre produtor e consumidor?
- Sei falar de compatibilidade sem reduzir tudo a número de versão?
Você concluiu este artigo
Próximo passo
Versionamento de API na prática Próximo passo →Compartilhar esta página
Copie o link manualmente no campo abaixo.