Qual a Melhor Estratégia de Versionamento de API: URL, Header ou Content Negotiation?

Ashley Innocent

Ashley Innocent

13 março 2026

Qual a Melhor Estratégia de Versionamento de API: URL, Header ou Content Negotiation?

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.

💡
Se você está construindo ou testando APIs REST, o Apidog ajuda a testar múltiplas versões de API, validar comportamentos específicos de cada versão e garantir a compatibilidade retroativa. Você pode manter especificações separadas para cada versão e executar testes em todas as versões simultaneamente.
button

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:

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:

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"

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:

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:

  1. Mês 1-6: Anuncie a descontinuação
  2. Mês 7-9: Adicione cabeçalhos de descontinuação
  3. Mês 10-11: Reduza os limites de taxa para a versão descontinuada
  4. 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.

button

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.

Pratique o design de API no Apidog

Descubra uma forma mais fácil de construir e usar APIs