Por que o versionamento é importante
Uma API é uma promessa. Uma vez que os clientes dependem dela, alterá-la descuidadamente quebra as aplicações deles, e clientes com erros custam caro para todos. O versionamento é a maneira de entregar melhorias enquanto oferece aos clientes um contrato estável e um caminho claro para a migração.
O objetivo não é evitar mudanças. É tornar a mudança previsível: saber quais alterações são seguras, expor as versões de forma consistente e aposentar as antigas seguindo um cronograma comunicado, em vez de surpreender as pessoas.
Mudanças disruptivas versus aditivas
A maior parte da dor no versionamento vem da falta de classificação das mudanças. Comece com uma regra clara.
Geralmente seguras (aditivas):
- Adicionar um novo campo opcional a uma resposta.
- Adicionar um novo endpoint.
- Adicionar um novo parâmetro de requisição opcional.
- Adicionar um novo valor de enum, desde que os clientes tolerem valores desconhecidos.
Disruptivas (exigem nova versão):
- Remover ou renomear um campo.
- Alterar o tipo ou formato de um campo.
- Tornar um parâmetro opcional em obrigatório.
- Alterar o significado ou o padrão de um comportamento existente.
- Alterar códigos de status ou a estrutura de erros dos quais os clientes dependem.
Projetar clientes para ignorar campos desconhecidos é a melhor maneira de manter as mudanças aditivas seguras. Documente essa regra para que ninguém precise adivinhar.
Estratégias de versionamento
Existem quatro formas comuns de permitir que os clientes selecionem uma versão.
Versioning via URI — a versão faz parte do caminho (path).
GET /v1/posts
GET /v2/posts
É visível, fácil de rotear, fácil de fazer cache e fácil de testar no navegador. É a escolha mais comum para APIs públicas, embora puristas argumentem que a URL não deveria mudar.
Versioning via Header — um header customizado seleciona a versão.
GET /posts
X-API-Version: 2
As URLs permanecem estáveis, o que é ótimo para cache por recurso, mas a versão fica invisível em logs, links e testes de navegador.
Versioning via Media-type — a negociação de conteúdo (content negotiation) seleciona a versão.
GET /posts
Accept: application/vnd.example.v2+json
Esta é a abordagem mais alinhada ao REST e se integra à negociação de conteúdo, mas é a mais difícil de descobrir e depurar.
Query parameter — ?version=2. Simples, mas fácil de omitir e problemático para cache.
Independentemente de qual você escolha, aplique-a de forma consistente e documente-a. Misturar estratégias é pior do que escolher uma menos popular.
Depreciação e sunset
Remover uma versão deve ser um processo, não um evento.
Deprecation: true
Sunset: Wed, 31 Dec 2026 23:59:59 GMT
Link: </v2/posts>; rel="successor-version"
- Depreciação anuncia que uma versão ou endpoint será removido.
- Sunset define a data exata em que ele deixará de funcionar.
- Link aponta para a substituição.
Combine os headers com um guia de migração, entradas no changelog e comunicação direta com os usuários mais ativos. Em seguida, monitore o uso: se uma parcela significativa do tráfego ainda estiver na versão antiga próximo à data de sunset, estenda o prazo em vez de quebrar esses clientes.
Executando versões lado a lado
Suportar duas versões significa que o código deve atender a ambas. Abordagens comuns:
- Handlers versionados que mapeiam para serviços compartilhados, para que a lógica de negócio permaneça em um único lugar.
- Adapters que traduzem a representação antiga para a nova.
- Feature flags para a implementação gradual de novos comportamentos.
- Specs separadas por versão, geradas e publicadas junto com a API.
Mantenha a diferença entre as versões pequena. Forks extensos de lógica são difíceis de manter e propensos a divergências.
Comunicando mudanças
O versionamento só funciona se os clientes souberem o que está acontecendo.
- Publique um changelog e marque as breaking changes de forma clara.
- Mantenha uma OpenAPI spec atualizada para cada versão.
- Envie avisos de depreciação nos headers e, sempre que possível, por e-mail.
- Forneça um guia de migração com exemplos de “antes e depois”.
- Ofereça uma janela de suporte que seja compatível com os ciclos de release dos seus usuários.
Melhores práticas
- Classifique cada alteração como aditiva ou breaking change antes de publicá-la.
- Prefira alterações aditivas; incremente a versão apenas quando for estritamente necessário.
- Escolha uma estratégia de versionamento e utilize-a em todo o projeto.
- Nunca remova um campo ou endpoint sem um período de depreciação.
- Anuncie a depreciação através de headers e com uma data de encerramento (sunset date).
- Monitore o tráfego por versão antes de descontinuar qualquer uma.
- Mantenha a lógica compartilhada atrás de adaptadores específicos de cada versão.
Erros comuns
- Quebrar clientes silenciosamente ao alterar a estrutura de uma resposta.
- Versionar cada pequena alteração, criando um fardo de manutenção.
- Misturar estratégias de versionamento na mesma API.
- Remover uma versão sem aviso prévio ou sem um caminho de migração.
- Deixar versões antigas rodando indefinidamente sem um plano de desativação.
- Esquecer de atualizar a documentação e as especificações de cada versão.
Próximos passos
O versionamento é o que permite que uma API sobreviva ao contato com clientes reais. Baseie-se em um design REST limpo, descreva cada versão com OpenAPI e utilize HTTP headers para comunicar a depreciação. Em seguida, escreva uma política de uma página para a sua própria API: o que é considerado uma mudança disruptiva (breaking change) e qual a vida útil de cada versão.