Por que versionar uma API?
APIs são contratos. Quebrar o contrato sem aviso derruba os clientes.
Uma API e um contrato entre o servidor e seus clientes. Quando você muda o contrato sem aviso, remove um campo, muda um tipo, renomeia um endpoint, todos os clientes que dependem da versão anterior quebram. Versionamento e a prática de manter versões anteriores funcionando enquanto novas versões são lancadas. Isso permite que clientes migrem no próprio ritmo sem ser forcados a atualizar imediatamente. Sem versionamento, qualquer mudanca na API vira uma crise de compatibilidade. Com versionamento bem planejado, evolução continua e incremental se torna rotina segura.
Versionamento por URL
A abordagem mais comum e a preferida pela maioria dos times por ser explícita e fácil de testar.
No versionamento por URL, a versão faz parte do path: /api/v1/users, /api/v2/users. Esta e a estrategia adotada por GitHub, Stripe, Twitter e a maioria das APIs públicas. As vantagens são claras: fácil de testar no browser ou Postman, fácil de logar e monitorar, e intuitivo para desenvolvedores novos. A desvantagem teórica e que "suja" a URL, mas na prática isso raramente e problema. Versões diferentes podem ser deployadas como serviços separados ou rotas separadas no mesmo serviço. E possível ter /v1 e /v2 rodando simultaneamente sem conflito.
Versionamento por header
Mais limpo na URL mas mais difícil de testar e descobrir.
No versionamento por header, a versão e enviada em um header HTTP customizado ou no header Accept: Accept: application/vnd.api+v2+json. O GitHub usa esse padrão como alternativa ao path versioning. A vantagem e que a URL permanece limpa: /api/users independente da versão. A desvantagem e que testar no browser torna-se mais complexo, logs de acesso não mostram a versão, e novos desenvolvedores não conseguem descobrir a versão apenas olhando a URL. Para APIs internas onde o cliente e controlado, pode fazer sentido. Para APIs públicas, a maioria prefere URL versioning pela descoberta facilitada.
Versionamento por query parameter
Evitar esta estrategia, polui URLs e complica o cache.
O versionamento por query parameter usa ?version=2 ou ?v=2 na URL. Algumas APIs antigas usam esse padrão, mas ele e considerado inferior pelas razões principais: complica o caching pois a URL muda, polui a query string que deveria ser usada para filtros e páginação, e mistura preocupações de controle de versão com parametros de negócio. Proxies e CDNs frequentemente ignoram query params ao fazer cache, o que pode causar respostas de versões erradas em cenários de cache. A recomendação geral de toda literatura sobre design de APIs REST e evitar query param versioning em favor de URL path ou headers.
O que e uma breaking change?
Qualquer mudanca que pode quebrar um cliente existente e uma breaking change.
Breaking changes são mudancas que tornam a versão anterior do cliente incompatível com a nova versão da API. Exemplos de breaking changes: remover um campo da response, mudar o tipo de um campo (string para int), renomear um endpoint, mudar o metodo HTTP de POST para PUT, adicionar um campo obrigatório no request, mudar a estrutura de um objeto aninhado. Exemplos de non-breaking changes: adicionar um campo opcional na response, adicionar um novo endpoint, adicionar um campo opcional no request, melhorar mensagens de erro. A regra geral e: clientes devem poder ignorar campos que não conhecem, isso e o princípio de tolerant reader.
Semantic versioning em APIs
MAJOR.MINOR.PATCH aplicado a APIs tem regras bem definidas.
Semantic versioning define MAJOR para breaking changes, MINOR para novas features retrocompatíveis e PATCH para bug fixes. Em APIs públicas com URL versioning, geralmente só o número MAJOR aparece na URL (/v1, /v2). Minor e patch podem ser gerenciados internamente sem criar novas versões na URL. Quando o MAJOR sobe, a versão anterior deve continuar funcionando por um período de deprecação. Documentar claramente o que mudou entre versões e essencial. Um changelog bem mantido reduz drasticamente o tempo que clientes levam para migrar, pois eles sabem exatamente o que precisa ser atualizado.
Deprecation e o header Sunset
Avisar clientes com antecedência e obrigação de qualquer API responsável.
O processo de deprecar uma versão de API deve começar com comunicação proativa. O header HTTP Deprecation indica que o endpoint ou versão esta sendo descontinuada. O header Sunset indica a data exata em que o endpoint sera removido: Sunset: Sat, 31 Dec 2026 23:59:59 GMT. Além dos headers, comunicar por email, changelog, documentação e status page. O período de deprecação deve ser suficiente para que clientes possam migrar, geralmente de 6 a 12 meses para APIs públicas. Remover uma versão sem comunicação adequada e uma das maiores violações de confianca que um provider de API pode cometer.
Estrategia de migração para clientes
Facilitar a migração aumenta a adesao e reduz tickets de suporte.
Além de comunicar a deprecação, o time de API deve facilitar a migração ativamente. Isso inclui: guia de migração com exemplos antes-depois para cada breaking change, ferramentas de codemods quando aplicável, suporte a duplo envio de campos antigos e novos por um período de transição, e eventualmente um migration endpoint que aceita requests no formato antigo e converte internamente. O GitHub disponibiliza preview versions de novas versões da API antes de serem lancadas oficialmente para que os clientes possam testar antes da transição obrigatória. Essa estrategia reduz muito o atrito da migração.
Exemplos reais de versionamento
Como GitHub, Stripe e Twitter fazem na prática.
O Stripe e referência em versionamento de API. Cada cliente fica "pinado" na versão da API no momento da integração. O Stripe manteve compatibilidade retroativa por anos enquanto lancava novas versões. O GitHub usa tanto URL versioning (/v3) quanto header versioning (Accept: application/vnd.github.v3+json). O Twitter usava /1.1 por anos antes de migrar para /2. A AWS raramente tem breaking changes porque versiona por data no path: /2023-01-01/. A lição desses exemplos e que API versioning bem feito e um investimento em reputação: desenvolvedores confiam em APIs que não quebram silenciosamente.
Resumo final
Versionar bem e respeitar os clientes que confiam na sua API.
Versionamento de API e sobre responsabilidade com os clientes que constroem em cima do seu sistema. A estrategia por URL e a mais prática e amplamente adotada. Breaking changes devem ser minimizadas e, quando inevitáveis, comunicadas com antecedência atraves dos headers Deprecation e Sunset. Non-breaking changes podem ser lancadas a qualquer momento sem nova versão. O período de deprecação deve ser generoso o suficiente para que os clientes possam migrar sem pressão. Uma API bem versionada e sinal de maturidade técnica e respeito pelos desenvolvedores que integram com ela.
Tutoriais em Video
Good APIs Vs Bad APIs: 7 Tips for API Design
What Is REST API? Examples And How To Use It, ByteByteGo
Rest API - Best Practices - Design
HTTP Crash Course & Exploration
APIs for Beginners - How to use an API
What Is A RESTful API?, Academind
Conceitos-chave
Versionamento por URL
api/v1/ api/v2/, mais explícito e fácil de testar, preferido pela maioria
Versionamento por header
Accept: application/vnd.api+v2+json, mais limpo na URL mas dificulta testes
Versionamento por parametro
?version=2, evitar, polui URLs e complica cache
Breaking change
Qualquer mudanca que quebra clientes, remover campo, mudar tipo, renomear endpoint
Deprecation
Avisar clientes com antecedência, header Deprecation e Sunset
Sunset strategy
Data de expiração com 6-12 meses de aviso e comunicação proativa
Versionamento no Instagram
@bytebytego
Reels, Versionamento de API
@bytebytego
Versionamento de API no Facebook
Versionamento de API no X (Twitter)
Links Uteis
O que devs dizem
Adotamos URL versioning com /v1 e /v2 rodando simultaneamente por seis meses. Nenhum cliente quebrou durante a migração. O segredo foi o changelog detalhado e o guia de migração com exemplos de request/response antes e depois.
O header Sunset mudou a relação com os consumidores da nossa API. Antes eles reclamavam de mudancas sem aviso. Agora veem o header nos logs e sabem exatamente quando a versão vai ser removida. Muito mais profissional.
Contract testing com Pact foi o que nos salvou de breaking changes involuntárias. Toda vez que o pipeline quebrava um contrato, sabiamos exatamente qual cliente ia ser afetado antes de chegar em produção.