Versionamento API: 8 estratégias para não quebrar contratos
Versionamento de API é o processo de gerenciar mudanças na interface da sua API de forma que consumidores existentes continuem funcionando. As estratégias mais usadas são versionamento por URI, query string, header, media type, data de lançamento, versão semântica, feature flags e versionamento por contrato. A escolha depende do acoplamento e do ecossistema.
Não existe estratégia universal. O que existe é o custo de quebrar um contrato versus o custo de manter versões antigas vivas. Abaixo, oito abordagens ordenadas pela frequência com que resolvem problemas reais, com critérios para decidir.
1. Versionamento por URI (/v1/recurso)
Colocar a versão no caminho é a estratégia mais visível e a mais fácil de operar. O consumidor vê /v1/pedidos e sabe exatamente o que está chamando. Roteadores, gateways e logs tratam versões como recursos distintos, o que simplifica observabilidade e cache. O custo aparece na proliferação de rotas: cada versão nova exige manutenção de código e documentação paralelos. Um critério prático: se sua API é pública e o time de suporte precisa explicar versões por telefone, URI resolve. Se o acoplamento é baixo e o consumidor é interno, pode ser peso desnecessário.
2. Versionamento por query string (?version=2)
Aqui a versão vira parâmetro, não caminho. A vantagem é que a URL base permanece estável, o que ajuda quando você não controla todos os clientes. A desvantagem é sutil: parâmetros de versão se misturam com filtros de negócio, e um cliente pode esquecer de enviá-lo. Nesse caso, o comportamento padrão precisa estar documentado. Se você adota essa estratégia, defina um valor default explícito e monitore chamadas sem versão. Sem isso, a query string vira fonte de bugs silenciosos.
3. Versionamento por header customizado
Enviar X-API-Version: 2 mantém a URL limpa e separa preocupações: o recurso é o mesmo, a representação é que muda. Funciona bem em APIs internas com clientes controlados. O problema é o cache. Proxies e CDNs, por padrão, não variam a resposta por header customizado, a menos que você configure Vary. Sem esse ajuste, um cliente pode receber a versão errada. É uma estratégia elegante que exige infraestrutura atenta.
4. Versionamento por media type (content negotiation)
Aqui a versão vive no Accept: application/vnd.suaempresa.v2+json. É o padrão mais alinhado ao REST e o mais difícil de explicar para quem não vive a especificação. Ganha em pureza conceitual e perde em adoção, porque exige que o consumidor monte headers complexos. Um contraexemplo útil: muitas APIs públicas abandonaram essa abordagem após medir a taxa de erro de clientes. Se o seu público é técnico e pequeno, vale considerar. Se é amplo, provavelmente não.
5. Versionamento por data de lançamento
Em vez de números, você usa datas: 2024-06-01. O ganho é que a versão comunica quando o contrato foi congelado, o que ajuda times a planejar migrações. O risco é a falsa sensação de compatibilidade: duas datas próximas podem conter mudanças incompatíveis. Stripe popularizou esse modelo, mas ele exige disciplina de documentação e um processo claro de depreciação. Sem isso, a data vira só um número maior.
6. Versionamento semântico (major.minor.patch)
Aplicar SemVer a APIs é tentador, mas exige rigor. Mudanças que quebram contrato sobem o major; adições compatíveis sobem o minor; correções sobem o patch. O problema é que "compatível" é uma decisão de julgamento, não um fato. Adicionar um campo obrigatório na resposta pode quebrar clientes que validam esquema. Se você adota SemVer, documente o que conta como breaking change. Caso contrário, a versão perde significado.
7. Feature flags em vez de versões
Nem toda mudança precisa de uma versão nova. Flags permitem liberar comportamento para um subconjunto de consumidores sem criar uma rota paralela. Isso reduz a superfície de manutenção e acelera testes. O cuidado é o acúmulo: flags antigas viram dívida técnica e precisam de data de remoção. Use quando a mudança é comportamental e reversível. Evite quando o contrato de dados muda de forma irreversível.
8. Versionamento por contrato (contract-first)
Aqui a versão nasce do contrato, não do código. Você define o esquema (OpenAPI, GraphQL SDL, Protobuf) e trata mudanças como alterações de contrato, com revisão e versionamento próprios. É a abordagem que melhor escala em times grandes, porque desacopla evolução de deploy. O custo é cultural: exige disciplina de revisão e ferramentas de compatibilidade. Se sua organização ainda trata contrato como documentação posterior, essa estratégia não vai funcionar sozinha.
Qual escolher na prática
Não existe resposta única, mas existe um critério: comece pelo consumidor. Se ele é externo e heterogêneo, priorize estratégias visíveis (URI, query string) e invista em depreciação comunicada. Se é interno e controlado, prefira header ou feature flags, que mantêm a URL estável. Em qualquer caso, defina por escrito o que conta como breaking change e quanto tempo uma versão antiga fica viva. Sem essas duas decisões, nenhuma estratégia segura o contrato.
FAQ
O que é versionamento de API?
É o processo de gerenciar mudanças na interface da API para que consumidores existentes continuem funcionando. Envolve decidir como identificar versões, o que conta como mudança incompatível e por quanto tempo versões antigas permanecem disponíveis. Sem isso, qualquer alteração vira risco de quebra silenciosa.
Qual a melhor estratégia de versionamento de API?
Depende do consumidor. APIs públicas e heterogêneas costumam se beneficiar de versionamento por URI, pela visibilidade. APIs internas e controladas podem usar header ou feature flags, mantendo a URL estável. O critério decisivo é o custo de quebrar contrato versus o custo de manter versões paralelas.
Quando devo criar uma nova versão da API?
Quando a mudança quebra o contrato existente: remover campo, alterar tipo, mudar semântica de resposta ou tornar parâmetro obrigatório. Adições compatíveis, como novos campos opcionais, geralmente não exigem nova versão. Documente o que conta como breaking change para evitar decisões inconsistentes entre times.
Como depreciar uma versão antiga sem quebrar clientes?
Comunicando cedo e medindo uso. Anuncie a depreciação com antecedência, exponha métricas de chamadas por versão e ofereça guia de migração. Desligue apenas quando o tráfego residual for conhecido e aceitável. Sem monitoramento, a depreciação vira aposta, não processo.
Versionamento semântico funciona para APIs?
Funciona se houver rigor na definição de compatibilidade. SemVer exige que o time saiba distinguir mudança major, minor e patch. Como "compatível" é julgamento, não fato, muitas equipes adotam SemVer e o esvaziam na prática. Só vale se o critério estiver documentado e revisado.
Feature flags substituem versionamento?
Não substituem, complementam. Flags ajudam em mudanças comportamentais reversíveis, liberando recursos para grupos específicos. Não resolvem alterações estruturais no contrato de dados. O risco é o acúmulo de flags antigas, que vira dívida técnica. Use com data de remoção definida.