O que Versionamento de API & Compatibilidade Retroativa faz?
Projete estratégias de versionamento de API que evoluem graciosamente sem quebrar consumidores existentes.
Gatilhos de Ativação
Ative em: "versionamento de API", "compatibilidade retroativa", "depreciação", "mudança disruptiva", "migração de API", "v1 v2", "cabeçalho sunset", "evolução de API", "mudança não disruptiva"
NÃO para: Evolução de schema de dados → schema-evolution-manager | Roteamento de versão em gateway → api-gateway-reverse-proxy-expert | Depreciação GraphQL → graphql-server-architect
Início Rápido
- Classifique a mudança — aditiva (segura), modificação (talvez disruptiva), remoção (disruptiva)
- Escolha a estratégia — caminho URL (
/v2/), cabeçalho (API-Version), ou negociação de conteúdo - Implemente cabeçalhos Sunset — RFC 8594 informa aos consumidores quando versões antigas morrem
- Execute versões em paralelo — mínimo de 6 meses de sobreposição para versões principais
- Monitore a adoção — acompanhe o tráfego por versão para saber quando retirar
Capacidades Principais
| Domínio | Tecnologias |
|---|---|
| Versionamento por URL | /api/v1/, /api/v2/ roteamento baseado em caminho |
| Versionamento por Cabeçalho | API-Version: 2024-01-15, Accept-Version |
| Negociação de Conteúdo | Accept: application/vnd.myapi.v2+json |
| Depreciação | Cabeçalho Sunset (RFC 8594), Cabeçalho Deprecation |
| Ferramentas | OpenAPI 3.1 overlays, Optic, Bump.sh |
Padrões de Arquitetura
Árvore de Decisão da Estratégia de Versionamento
É apenas aditiva? (novos campos, novos endpoints)
├─ SIM → Sem bump de versão necessária (compatível retroativo)
└─ NÃO → É uma renomeação/alteração de tipo de campo?
├─ SIM → Você pode manter ambos os campos (antigo + novo)?
│ ├─ SIM → Adicione o novo, deprecie o antigo (versão menor)
│ └─ NÃO → Bump de versão principal (v1 → v2)
└─ NÃO → É uma remoção?
└─ SIM → Bump de versão principal com período sunset
Implantação de Versão Paralela
// Roteador Express com roteamento baseado em versão
import { Router } from 'express';
const v1Router = Router();
const v2Router = Router();
// v1: retorna { name: string }
v1Router.get('/users/:id', async (req, res) => {
const user = await getUser(req.params.id);
res.json({ name: user.fullName }); // formato legado
});
// v2: retorna { firstName, lastName, displayName }
v2Router.get('/users/:id', async (req, res) => {
const user = await getUser(req.params.id);
res.json({
firstName: user.firstName,
lastName: user.lastName,
displayName: user.fullName,
});
});
app.use('/api/v1', v1Router);
app.use('/api/v2', v2Router);
// Middleware de cabeçalho Sunset para v1
v1Router.use((req, res, next) => {
res.set('Sunset', 'Sat, 01 Nov 2026 00:00:00 GMT');
res.set('Deprecation', 'true');
res.set('Link', '</api/v2>; rel="successor-version"');
next();
});
Versionamento Baseado em Data (Modelo Stripe)
API-Version: 2026-03-15
Mudanças são vinculadas a datas, não a números inteiros:
2026-01-01 → linha de base
2026-03-15 → renomeou `name` → `display_name`
2026-06-01 → removeu `legacy_field`
O servidor fixa requisições sem versão na versão padrão da conta.
Cada versão é uma camada de transformação sobre o modelo interno canônico.
Anti-Padrões
- Versionar com muita pressa — a maioria das mudanças é aditiva e não requer bump de versão; adicione campos livremente
- Sem cronograma sunset — depreciar sem uma data concreta de desligamento significa que as versões vivem para sempre
- Copiar controladores inteiros — use uma camada de transformação/adaptação, não lógica de negócio duplicada por versão
- Ignorar campos desconhecidos — APIs devem ser leitores tolerantes; ignore campos desconhecidos na entrada (Lei de Postel)
- Mudanças disruptivas em versões menores — se os consumidores dependiam disso, removê-lo é disruptivo independentemente de sua intenção
Lista de Verificação de Qualidade
- Mudanças aditivas (novos campos, novos endpoints) são enviadas sem bump de versão
- Mudanças disruptivas exigem versão principal com período sunset de 6+ meses
- Cabeçalho Sunset (RFC 8594) definido em versões depreciadas
- Cabeçalho Link aponta os consumidores para a versão sucessora
- Tráfego por versão monitorado para acompanhar o progresso da migração
- Especificação OpenAPI publicada por versão com ferramentas de diff (Optic/Bump.sh)
- Plano de notificação ao consumidor: changelog, e-mail, aviso no painel
- Roteamento de versão tratado no nível do gateway, não no código da aplicação
- Testes de integração validam compatibilidade retroativa (testes de contrato)