Versionamento de API que sobrevive três anos
Versionamento de API não é escolher `/v1` versus `/v2` no path. É contrato multianual com cada cliente — incluindo os que ainda não existem. Versionar o que quebra. Sunset o que telemetria prova sem uso. Expandir todo o resto.
Ano um: REST API limpa, prefixo /v1, docs swagger. Ano dois: app mobile, três parceiros de integração, ferramentas admin internas. Ano três: rename de campo breaking shipa num deploy de sexta. Webhooks de parceiros falham em silêncio. Clientes mobile em builds antigos crasham ao parsear. Ninguém sabe quais consumidores ainda chamam o endpoint deprecado porque logging não capturava client identity. Estratégia de versionamento de API que sobrevive três anos não é sintaxe — é política: o que pode mudar sem aviso, o que exige nova versão, quanto tempo versões antigas vivem e como sunset é medido — não adivinhado.
APIs são contratos mais longos que a maioria dos codebases. Clientes externos atualizam nos calendários deles, não no seu. Apps mobile ficam em app stores por meses. Integrações enterprise exigem trimestres de aviso. Serviços internos se multiplicam sem que ninguém perceba. Versionamento é como equipes mudam APIs em produção sem fingir que todo consumidor deploya simultaneamente.
Versionar o que quebra; expandir o que não
| Change type | Strategy | Example |
|---|---|---|
| Adicionar campo opcional | Sem version bump | Novo campo JSON, ignorado por clientes antigos |
| Adicionar endpoint opcional | Sem version bump | Nova rota, rotas antigas inalteradas |
| Renomear campo | Breaking — versão ou alias | user_name → display_name com período de dual-write |
| Remover campo | Breaking — versão + sunset | Deprecation header, telemetria, depois removal |
| Mudar semântica | Breaking — versão | status: "active" agora exclui trial |
| Mudar auth | Breaking — versão | Mudanças de OAuth scope, mudanças de formato de key |
| Só performance | Geralmente não versionado | Resposta mais rápida, mesma shape |
Mudanças aditivas são o default. Breaking changes exigem incremento de versão OU camada de compatibilidade com sunset documentado.
/v2na URL não é estratégia de versionamento. É rótulo. Política é a estratégia.
O padrão strangler fig legacy migration se aplica a APIs — rotear tráfego para implementações novas atrás de fachada enquanto versão antiga decai com tráfego medido, não datas arbitrárias.
Estilos de versionamento e tradeoffs
URL path (/v1/users). Visível, fácil de rotear no gateway. Risco: clientes hardcodam path; proliferam URLs de recursos.
Header (Accept: application/vnd.company.v2+json). URLs limpas. Risco: mais difícil testar no browser; clientes esquecem header.
Query param (?api-version=2024-01-01). Clareza baseada em data. Risco: erros de caching; params removidos por proxies.
Content negotiation. Conforme padrões. Risco: complexidade; suporte inconsistente em clientes.
Escolher um estilo primário por superfície de API. Misturar estilos entre endpoints confunde consumidores e observabilidade. Documentar a escolha onde integradores aterrisam primeiro — developer portal, banner no OpenAPI spec, mensagens de erro em chamadas deprecadas.
Versões baseadas em data (2024-06-01) comunicam timelines de sunset melhor que inteiros opacos (v3). Inteiros servem internamente se changelog mapeia integer → date → deprecation policy.
Deprecation é produto com telemetria
Sunset sem dados de uso é vandalismo contra integradores.
Deprecation headers em cada resposta de versão antiga:
Deprecation: true
Sunset: Sat, 01 Mar 2027 00:00:00 GMT
Link: <https://docs.example.com/migration/v1-to-v2>; rel="successor-version"
Métricas por cliente/versão:
- Requests por versão de API por dia
- Client IDs únicos ou API keys por versão
- Error rates em campos deprecados
- Versão de cliente ativa mais antiga
Política de sunset escrita de antemão:
- Período mínimo de aviso (90 dias consumer, 180 dias enterprise — ajustar a contratos)
- Outreach ativo quando client ID ainda em versão deprecada em T-60 dias
- Hard sunset só quando tráfego abaixo do threshold OU aviso contratual completo
Nunca remover versão que telemetria mostra com integrações ativas pagantes sem sign-off de owner nomeado.
Padrões de compatibilidade que adiam forks de versão
Antes de criar /v2, esgotar compatibilidade:
Field aliasing. Retornar user_name e display_name durante transição. Write aceita ambos. Remover alias após sunset.
Default values para campos required novos. Server fornece default sensato quando clientes antigos omitem campo — documentar no changelog.
Response shaping por versão. Gateway ou camada handler mapeia modelo interno para shape v1 ou v2 — acumula mapping debt mas evita dupla implementação.
Feature flags para mudanças de comportamento. Mesmo endpoint, flag controla semântica nova — útil para clientes internos; APIs externas preferem versões explícitas.
Camadas de mapping se acumulam. Rastrear mapping debt — quando manutenção de alias supera custo de nova versão, forkear versão e sunset v1 em calendário.
Documentação e changelog como infraestrutura de versionamento
Integradores leem changelogs, não commit history.
- Breaking change log — data, endpoints afetados, passos de migração, data de sunset.
- OpenAPI por versão — specs separados ou spec único versionado com tags claras.
- Migration guides — code samples para linguagens principais de clientes, não só prosa.
- Webhook versioning — topic separado ou campo payload version; parceiros perdem versionamento por URL.
OAuth scopes e design de autorização intersecta versionamento — mudanças de scope são breaking para clientes com tokens antigos. Versionar requisitos de auth explicitamente no changelog.
Como equipes devem projetar versionamento de API a longo prazo?
Estas políticas previnem version sprawl e breakages surpresa.
Quantas versões ativas devem rodar simultaneamente?
Tipicamente duas — atual e anterior. Três cria tripla carga de manutenção. Exceção: contratos enterprise que exigem suporte estendido — cobrar ou documentar como custo ligado a revenue.
Quando nova versão major é obrigatória?
Quando custo de camada de compatibilidade supera fork, quando mudança semântica não pode ser aliased, ou quando segurança exige quebrar auth antiga. Não quando rename ficaria mais limpo — limpeza não é critério de breaking change.
Como clientes mobile afetam timelines de sunset?
Mobile fica meses atrás do server — app store review, taxas de update de usuários. Política de sunset deve exceder cauda mobile; feature flags server-driven não corrigem parse errors de binários antigos. Manter shapes de resposta antigas até analytics mostrar tráfego negligible de versões antigas de app.
Um argumento comum vai na direção oposta
A visão oposta sustenta que versionamento estrito freia inovação — que equipes deveriam shippar breaking changes rápido e esperar que clientes acompanhem.
Clientes que pagam faturas não acompanham cadência de sprint. Quebrar APIs sem versionamento transfere velocidade de engenharia para customer support e churn. Política additive-first com breaks versionados raros é mais rápida no net — menos fire drills, menos chamadas de emergência a parceiros.
GraphQL e padrões BFF deslocam onde vive versionamento mas não eliminam disciplina de contrato — regras de schema deprecation aplicam igual.
Key takeaways
- Versionar só breaking changes — campos e endpoints aditivos não precisam version bump.
- Escolher um estilo de versionamento; documentar política de sunset antes de shippar v1.
- Deprecation headers, telemetria por cliente/versão e períodos mínimos de aviso são obrigatórios.
- Field aliasing e response shaping adiam forks — rastrear mapping debt.
- Clientes mobile e enterprise estendem timelines de sunset — medir, não adivinhar.
- Changelog e migration guides são infraestrutura de versionamento, não afterthoughts.
Conclusion
Versionamento de API que sobrevive três anos se mede em política e telemetria, não em prefixos de path. Equipes que registram uso de versão por cliente, deprecam com aviso e expandem antes de quebrar mantêm confiança com integradores que nunca conhecerão. Equipes que quebram campos em deploys de sexta mantêm backlog de parceiros irritados.
A auditoria: listar versões ativas de API, volume de requests por versão, cliente mais antigo ainda em cada uma. Se alguma versão carece de data de sunset e métrica de tráfego, esse é o platform work deste trimestre.