TL;DR
O versionamento por URL (/v1/pets) é a estratégia de versionamento de API mais prática para a maioria das equipes. É visível, cacheável e fácil de testar. O versionamento por cabeçalho e a negociação de conteúdo são mais "puramente" REST, mas adicionam complexidade. A Modern PetstoreAPI utiliza o versionamento por URL com versionamento semântico e políticas de descontinuação claras.
Introdução
Sua API precisa de uma alteração drástica (breaking change). Você está mudando o formato de resposta para /pets de um array simples para um objeto encapsulado com metadados de paginação. Clientes existentes serão afetados. O que você faz?
Você precisa de versionamento de API. Mas qual estratégia? Versionamento por URL (/v1/pets vs /v2/pets)? Versionamento por cabeçalho (Accept: application/vnd.petstore.v1+json)? Negociação de conteúdo? Cada abordagem tem defensores apaixonados e opiniões fortes.
A resposta: o versionamento por URL é a melhor opção para a maioria das equipes. É pragmático, visível e funciona com todas as ferramentas HTTP. O versionamento por cabeçalho e a negociação de conteúdo são teoricamente mais limpos, mas adicionam uma complexidade que a maioria das equipes não precisa.
A Modern PetstoreAPI utiliza versionamento por URL com versionamento semântico e políticas claras de descontinuação. A versão atual é v1, com a v2 planejada para futuras alterações drásticas.
Neste guia, você aprenderá as três principais estratégias de versionamento, suas vantagens e desvantagens, e como implementar o versionamento corretamente usando a Modern PetstoreAPI como referência.
Por que as APIs precisam de versionamento
As APIs evoluem. Você adiciona funcionalidades, corrige bugs e melhora designs. Às vezes, essas mudanças afetam clientes existentes.
Alterações Drásticas (Breaking Changes)
Alterações que afetam clientes existentes:
1. Remoção de campos:
// v1
{"id": "123", "name": "Fluffy", "age": 3}
// v2 (breaking: removed age)
{"id": "123", "name": "Fluffy"}
2. Mudança de tipos de campo:
// v1
{"price": "19.99"}
// v2 (breaking: string to number)
{"price": 19.99}
3. Mudança na estrutura da resposta:
// v1 (bare array)
[{"id": "123"}]
// v2 (breaking: wrapped object)
{"data": [{"id": "123"}], "pagination": {...}}
4. Mudança na estrutura da URL:
// v1
GET /pet/123
// v2 (breaking: plural)
GET /pets/123
5. Mudança de autenticação:
// v1: API key in query
GET /pets?api_key=xxx
// v2 (breaking: Bearer token)
GET /pets
Authorization: Bearer xxx
Alterações Não Drásticas (Non-Breaking Changes)
Alterações que não afetam clientes:
- Adicionar novos endpoints
- Adicionar campos opcionais às requisições
- Adicionar novos campos às respostas (clientes devem ignorar campos desconhecidos)
- Adicionar novos parâmetros de consulta
- Adicionar novos métodos HTTP a recursos existentes
A Decisão de Versionamento
Quando você precisa de uma alteração drástica, você tem duas opções:
1. Forçar todos os clientes a atualizarem - Simples, mas quebra integrações existentes
2. Suportar múltiplas versões - Mais trabalho, mas mantém a compatibilidade retroativa
A maioria das APIs públicas escolhe a opção 2. O versionamento permite que você evolua a API enquanto dá tempo aos clientes para migrarem.
Versionamento por URL
O versionamento por URL coloca o número da versão no caminho da URL.
Como Funciona
GET /v1/pets
GET /v2/pets
A versão faz parte do identificador do recurso. Versões diferentes são recursos diferentes.
Vantagens
1. Visível e explícito
A versão está na URL. Você pode vê-la nos logs, histórico do navegador e documentação. Não há cabeçalhos ocultos para lembrar.
2. Fácil de testar
curl https://petstoreapi.com/v1/pets
curl https://petstoreapi.com/v2/pets
Você pode testar ambas as versões com requisições HTTP simples.
3. Funciona com todas as ferramentas HTTP
Navegadores, caches, proxies e balanceadores de carga veem URLs diferentes. Eles podem rotear, armazenar em cache e registrar cada versão independentemente.
4. Simples para clientes
Clientes apenas mudam a URL. Sem cabeçalhos personalizados ou lógica de negociação de conteúdo.
5. Fácil de descontinuar
Você pode remover os endpoints /v1 sem afetar /v2.
Desvantagens
1. Não é REST "puro"
Puristas REST argumentam que /v1/pets/123 e /v2/pets/123 são o mesmo recurso, então deveriam ter a mesma URL. A versão deveria estar nos cabeçalhos ou na negociação de conteúdo.
2. Poluição de URL
Sua API tem múltiplos espaços de URL: /v1/*, /v2/*, etc.
3. Mais difícil de versionar recursos individuais
Se você quiser versionar apenas um endpoint, você precisa versionar a API inteira ou criar inconsistência.
Implementação
Versão principal na URL:
/v1/pets
/v2/pets
Não inclua versões menores:
❌ /v1.2/pets (muito granular)
✅ /v1/pets (apenas versão principal)
Use versionamento semântico internamente:
- v1.0.0 - Lançamento inicial
- v1.1.0 - Adição de novos campos (não drástica)
- v1.2.0 - Adição de novos endpoints (não drástica)
- v2.0.0 - Alterações drásticas (nova URL: /v2)
A Modern PetstoreAPI utiliza versionamento por URL com /v1 como a versão atual.
Versionamento por Cabeçalho
O versionamento por cabeçalho coloca a versão em um cabeçalho HTTP personalizado.
Como Funciona
GET /pets
API-Version: 1
GET /pets
API-Version: 2
A URL permanece a mesma. O cabeçalho especifica a versão.
Vantagens
1. URLs limpas
/pets é o mesmo para todas as versões. Sem prefixo /v1 ou /v2.
2. Mais "RESTful"
O identificador do recurso (/pets/123) não muda. A representação muda com base no cabeçalho.
3. Versionamento granular
Você pode versionar recursos individuais:
GET /pets
API-Version: 2
GET /orders
API-Version: 1
Desvantagens
1. Invisível
A versão não está na URL. Você não consegue vê-la nos logs ou histórico do navegador sem verificar os cabeçalhos.
2. Mais difícil de testar
curl -H "API-Version: 1" https://petstoreapi.com/pets
curl -H "API-Version: 2" https://petstoreapi.com/pets
Você deve lembrar de incluir o cabeçalho.
3. Complexidade de caching
Caches devem considerar o cabeçalho API-Version. Você precisa de Vary: API-Version nas respostas.
4. Complexidade do cliente
Clientes precisam de lógica de cabeçalho personalizada. Nem todos os clientes HTTP tornam isso fácil.
5. Ambiguidade da versão padrão
O que acontece se o cliente não enviar o cabeçalho? Você precisa de um padrão, o que cria um comportamento implícito.
Implementação
Cabeçalho personalizado:
API-Version: 1
Ou use o cabeçalho Accept:
Accept: application/vnd.petstore.v1+json
Inclua o cabeçalho Vary:
Vary: API-Version
Isso informa aos caches para considerar o cabeçalho ao armazenar em cache.
Negociação de Conteúdo
A negociação de conteúdo usa o cabeçalho Accept com tipos de mídia personalizados.
Como Funciona
GET /pets
Accept: application/vnd.petstore.v1+json
GET /pets
Accept: application/vnd.petstore.v2+json
A versão faz parte do tipo de mídia.
Vantagens
1. O mais "RESTful"
É assim que o REST foi projetado. Diferentes representações do mesmo recurso.
2. Segue os padrões HTTP
Usa negociação de conteúdo HTTP padrão.
3. Suporta múltiplos formatos
Você pode versionar e formatar simultaneamente:
Accept: application/vnd.petstore.v1+json
Accept: application/vnd.petstore.v1+xml
Desvantagens
1. Complexo
Clientes devem entender tipos de mídia e negociação de conteúdo.
2. Mais difícil de testar
curl -H "Accept: application/vnd.petstore.v1+json" https://petstoreapi.com/pets
3. Pouco suporte de ferramentas
Muitos clientes e ferramentas HTTP não lidam bem com tipos de mídia personalizados.
4. Complexidade de caching
Caches devem considerar o cabeçalho Accept. Você precisa de Vary: Accept.
5. Exagerado para a maioria das APIs
A maioria das APIs não precisa desse nível de sofisticação.
Implementação
Tipo de mídia específico do fornecedor:
Accept: application/vnd.petstore.v1+json
Resposta:
Content-Type: application/vnd.petstore.v1+json
Vary: Accept
Como a Modern PetstoreAPI implementa o versionamento
A Modern PetstoreAPI utiliza versionamento por URL com políticas claras.
Versão Atual: v1
https://petstoreapi.com/v1/pets
https://petstoreapi.com/v1/orders
https://petstoreapi.com/v1/users
Todos os endpoints estão sob /v1.
Cabeçalho de Resposta da Versão
Toda resposta inclui a versão da API:
X-API-Version: 1.2.0
Isso mostra a versão exata (major.minor.patch), mesmo que a URL mostre apenas a versão principal.
Avisos de Descontinuação
Quando uma versão é descontinuada, as respostas incluem:
Deprecation: true
Sunset: Sat, 31 Dec 2026 23:59:59 GMT
Link: <https://docs.petstoreapi.com/migration/v1-to-v2>; rel="deprecation"
Deprecation- Indica que a versão está descontinuadaSunset- Quando a versão será removidaLink- Guia de migração
Descoberta de Versão
O endpoint raiz lista as versões disponíveis:
GET https://petstoreapi.com/
{
"versions": [
{
"version": "v1",
"status": "current",
"docsUrl": "https://docs.petstoreapi.com/v1"
}
]
}
Versionamento Semântico
A Modern PetstoreAPI segue o versionamento semântico internamente:
- Principal (v1, v2) - Alterações drásticas, nova URL
- Secundária (v1.1, v1.2) - Novas funcionalidades, compatível retroativamente
- De Correção (v1.1.1, v1.1.2) - Correções de bugs, compatível retroativamente
Apenas as versões principais aparecem nas URLs.
Testando Versões de API com Apidog
O Apidog ajuda você a testar múltiplas versões de API.
Importar Múltiplas Versões
Importe as especificações OpenAPI para cada versão:
petstore-v1.yaml → Environment: v1
petstore-v2.yaml → Environment: v2
Executar Testes em Todas as Versões
Crie suites de teste que executam em ambas as versões:
// Test v1
pm.environment.set("baseUrl", "https://petstoreapi.com/v1");
pm.sendRequest(pm.environment.get("baseUrl") + "/pets");
// Test v2
pm.environment.set("baseUrl", "https://petstoreapi.com/v2");
pm.sendRequest(pm.environment.get("baseUrl") + "/pets");
Validar Comportamento Específico da Versão
Teste se v1 e v2 se comportam de forma diferente:
// v1 returns bare array
pm.test("v1 returns array", function() {
pm.expect(pm.response.json()).to.be.an('array');
});
// v2 returns wrapped object
pm.test("v2 returns wrapped object", function() {
pm.expect(pm.response.json()).to.have.property('data');
pm.expect(pm.response.json()).to.have.property('pagination');
});
Verificar Cabeçalhos de Descontinuação
Teste se as versões descontinuadas incluem os cabeçalhos apropriados:
pm.test("Deprecated version includes headers", function() {
pm.response.to.have.header("Deprecation");
pm.response.to.have.header("Sunset");
});
Estratégia de Descontinuação de Versões
Como descontinuar versões antigas sem afetar clientes.
1. Anuncie a Descontinuação Cedo
Dê aos clientes um aviso de pelo menos 6 a 12 meses:
Deprecation: true
Sunset: Sat, 31 Dec 2026 23:59:59 GMT
2. Forneça um Guia de Migração
Documente todas as alterações drásticas e como migrar:
Link: <https://docs.petstoreapi.com/migration/v1-to-v2>; rel="deprecation"
3. Monitore o Uso
Monitore quais clientes ainda usam versões descontinuadas:
X-API-Version: 1.2.0
X-Client-ID: abc123
Contate os clientes diretamente, se necessário.
4. Desligamento Gradual
Não remova a versão imediatamente:
- Mês 1-6: Anuncie a descontinuação
- Mês 7-9: Adicione cabeçalhos de descontinuação
- Mês 10-11: Reduza os limites de taxa para a versão descontinuada
- Mês 12: Remova a versão descontinuada
5. Mantenha a Documentação
Mesmo após a remoção, mantenha a documentação da versão antiga. Os clientes podem precisar consultá-la.
Conclusão
O versionamento por URL é a estratégia de versionamento de API mais prática para a maioria das equipes. É visível, fácil de testar e funciona com todas as ferramentas HTTP. O versionamento por cabeçalho e a negociação de conteúdo são mais "puramente" REST, mas adicionam complexidade.
A Modern PetstoreAPI utiliza versionamento por URL com /v1 como a versão atual, versionamento semântico internamente e políticas claras de descontinuação. Esta abordagem equilibra o pragmatismo com um bom design de API.
Use o Apidog para testar múltiplas versões de API, validar comportamentos específicos da versão e garantir migrações tranquilas entre as versões.
Perguntas Frequentes
Devo usar versionamento por URL ou por cabeçalho?
Use o versionamento por URL, a menos que você tenha um motivo específico para não fazê-lo. É mais simples, mais visível e mais fácil de testar. O versionamento por cabeçalho é mais "RESTful", mas adiciona uma complexidade que a maioria das equipes não precisa.
Quantas versões devo suportar simultaneamente?
Suporte no máximo 2 versões: a atual e a anterior. Suportar mais cria uma carga de manutenção. Dê aos clientes de 6 a 12 meses para migrar, depois remova as versões antigas.
Devo versionar a partir de v0 ou v1?
Comece com v1. v0 implica instabilidade. Se sua API não é estável o suficiente para v1, não a lance publicamente ainda.
Preciso versionar todos os endpoints?
Não. Versionar apenas quando você faz alterações drásticas. Se você adicionar novos endpoints sem alterar os existentes, você não precisa de uma nova versão.
E as versões menores nas URLs?
Não inclua versões menores nas URLs. Use /v1, não /v1.2. Versões menores são compatíveis retroativamente, então os clientes não precisam mudar as URLs.
Como lido com bugs específicos da versão?
Corrija bugs em todas as versões suportadas. Se um bug existe apenas em v1, corrija-o em v1. Não force os clientes a atualizarem para v2 para correções de bugs.
Devo usar versionamento semântico?
Sim, internamente. Monitore as versões major.minor.patch, mas exponha apenas as versões principais nas URLs. Isso lhe dá flexibilidade para alterações não drásticas.
E se eu precisar versionar apenas um endpoint?
Com o versionamento por URL, você precisaria versionar a API inteira ou criar inconsistência. Isso é uma troca. A maioria das equipes aceita versionar a API inteira pela simplicidade.
