Como depreciar uma API sem perder seus desenvolvedores
7 min de leitura
Depreciar uma API é anunciar que algo ainda funciona hoje e vai parar de funcionar em uma data declarada, e então cumprir as duas metades dessa promessa. A maioria das depreciações falha na segunda metade: a data escorrega silenciosamente, ou chega e os chamadores que nunca viram o aviso descobrem por um erro. Uma depreciação está terminada quando todo chamador afetado migrou ou recebeu, individualmente, a informação de que não migrou.
O que é depreciação de API?
Depreciação é o período entre anunciar que um endpoint, campo ou versão vai sumir e realmente removê-lo. Durante esse período o comportamento antigo continua funcionando, a documentação diz que está saindo, e toda resposta carrega um aviso legível por máquina. Remoção é o evento separado, posterior, muitas vezes chamado de sunset. Os dois se confundem, e essa confusão é onde o dano acontece: “deprecated” começa a significar “pode já ter sumido”, e os chamadores param de confiar em nenhuma das duas palavras.
| Termo | Significado | No que os chamadores podem confiar |
|---|---|---|
| Deprecated | Anunciado como saindo, ainda funciona | Comportamento completo até a data de sunset |
| Sunset | A data em que para de funcionar | Nada depois dessa data |
| Retired / removido | Sumiu; requisições falham | Um erro, idealmente um que nomeie o substituto |
| Legacy | Indefinido. Evite a palavra | Nada, que é o problema |
Quanto tempo deveria durar um período de depreciação?
O suficiente para um chamador descobrir e fazer o trabalho, medido a partir de quando o aviso o alcançou, não a partir de quando vocês o escreveram. Noventa dias é o piso comum para uma API web pública. Doze meses é normal para qualquer coisa embutida em software que usuários finais instalam, porque a correção também precisa passar pelo processo de release deles. A orientação de versionamento do Google, a AIP-185, pede um período de transição razoável e recomenda 180 dias mesmo antes de remover funcionalidades beta, e o Kubernetes documenta sua política de depreciação em contagem de releases em vez de meses, o que é a unidade certa quando os chamadores de vocês atualizam por versão.
Escolham um período, escrevam-no como política, e parem de decidi-lo por mudança. Uma política publicada transforma cada depreciação de uma negociação em uma aplicação de regra.
Escrever a política de depreciação cobre o início da janela; descontinuando uma versão de API cobre o aviso separado necessário no final, quando o período realmente acaba e a versão para de funcionar.
O cronograma de depreciação
Quatro datas, anunciadas juntas no primeiro dia. Cada uma é uma entrada de changelog separada quando chega, então a história é contada quatro vezes a quem só lê o changelog.
- Anunciar. A entrada diz o que está sendo depreciado, por quê, o que o substitui, e a data de sunset. A documentação da coisa antiga ganha um banner que linka para a migração. As respostas ganham os headers descritos abaixo.
- Lembrar, na metade do caminho. Uma segunda entrada, e uma mensagem direta a todo chamador ainda usando o comportamento antigo. Este é o passo que precisa de dados de uso: se vocês não conseguem listar quem ainda está chamando o endpoint depreciado, vocês não conseguem fazer isso, e vale a pena corrigir antes da próxima depreciação.
- Brownout, pouco antes da data. Retorne erros para o comportamento antigo por uma janela curta, uma hora ou um dia, depois restaure. Chamadores que perderam todo aviso descobrem agora, enquanto ainda há tempo. O GitHub usou brownouts programados antes de aposentar a autenticação por senha para a API, e é o passo individual mais eficaz desta lista.
- Sunset. Remova. O erro que o substitui nomeia o substituto e linka o guia de migração. Mantenha o erro no lugar por muito tempo; um 404 não diz nada a um chamador.
O que um aviso de depreciação deveria dizer?
Um aviso de depreciação diz o que está saindo, quando para, o que usar em vez disso, e quem é afetado. Aqui está a forma, preenchida:
GET /v1/reports/dailyestá depreciado e para de funcionar em 1º de março de 2027. É substituído porGET /v2/reports?granularity=day, que retorna os mesmos dados com um esquema estável e paginação. Afeta as 214 integrações que chamaram o endpoint v1 nos últimos 30 dias; se a sua for uma delas, você também receberá este aviso por e-mail. Guia de migração: [link]. Nada muda até 1º de março de 2027. A partir dessa data o endpoint v1 retorna410 Gonecom um link para esta entrada.
Toda frase carrega algo de que a leitora precisa. A contagem de integrações afetadas diz a cada leitora se ela deve continuar lendo. “Nada muda até” é a frase que permite que quem não é afetado feche a aba. A página exemplos de changelog reúne entradas de equipes que escrevem essa forma consistentemente, e vale a pena ler três antes de escrever a primeira própria.
Quais headers um endpoint depreciado deveria enviar?
Envie Deprecation, Sunset e um Link para o sucessor, em toda resposta do endpoint
depreciado, a partir do dia do anúncio. O header Deprecation
carrega a data em que a depreciação entrou em vigor; o
header Sunset carrega a data em que o endpoint
para de responder; Link: <url>; rel="successor-version" aponta para o que usar em vez disso.
HTTP/1.1 200 OK
Deprecation: @1756425600
Sunset: Mon, 01 Mar 2027 00:00:00 GMT
Link: <https://api.example.com/v2/reports>; rel="successor-version"
Link: <https://example.com/changelog/daily-reports>; rel="deprecation"
A maioria dos chamadores nunca vai ler os headers pessoalmente. O valor deles está em que o cliente HTTP, o gateway ou o monitoramento de um chamador pode, o que transforma a depreciação de vocês em um alerta do lado deles em vez de uma página do lado de vocês. SDKs que vocês enviam deveriam registrar um aviso quando virem um.
Quem foi informado, e como vocês sabem?
Este é o passo que decide se o sunset é tranquilo ou um incidente de suporte, e é o mais difícil de fazer só com um changelog. Uma entrada de changelog informa todo mundo que lê o changelog. Uma depreciação precisa alcançar as pessoas específicas cujo código vai falhar, e a forma usual de encontrá-las é os mesmos dados de uso de que precisa o lembrete na metade do caminho: as chaves de API, apps ou contas que chamaram o comportamento depreciado recentemente.
O ciclo que rodamos: a entrada é redigida a partir do pull request que adiciona a depreciação, uma pessoa revisa a formulação e a data, e uma vez publicada a entrada em si é a notificação. Quem mandou pelo widget um feedback sobre o problema, ou um pedido pelo substituto, que virou uma issue do GitHub fechada pelo pull request, recebe um comentário nessa issue dizendo que foi lançado, com um link para a entrada. Feed e widget servem a mesma entrada a todos os outros, junto com cada outra entrada no changelog de API. O que não fazemos é deixar a depreciação virar “lançada” antes de uma pessoa tê-la publicado; um aviso com a data errada é pior que nenhum aviso.
Seja qual for a ferramenta de vocês, a pergunta que você deve conseguir responder no dia do sunset é: quais chamadores ainda estavam usando isso na semana passada, e quais deles avisamos diretamente? Se a resposta for “publicamos algo sobre isso”, o sunset não está pronto.
Qual é a diferença entre depreciar e versionar?
Versionar é como você mantém o comportamento antigo disponível enquanto o novo existe; depreciação é como você aposenta o antigo. Uma nova versão de API sem uma política de depreciação para a anterior é um compromisso de rodar as duas para sempre. Uma depreciação sem versionamento é uma mudança que quebra algo com atraso. Vocês precisam de ambos, e a versão é a metade mais fácil. O GraphQL é a exceção que vale a pena nomear: geralmente não existe nenhum número de versão para incrementar, e depreciação de schema no GraphQL cobre como um único schema compartilhado aposenta um campo com uma diretiva em vez disso.
FAQ
Um endpoint depreciado deveria continuar funcionando exatamente como antes? Sim, até a data de sunset. As únicas mudanças permitidas são os headers adicionados e, perto do fim, um brownout programado que vocês anunciaram com antecedência.
Qual código de status um endpoint aposentado deveria retornar?
410 Gone, com um corpo e um header Link apontando para o substituto e a entrada de changelog.
404 diz que a URL nunca existiu, o que é falso e inútil.
Um período de depreciação pode ser encurtado? Só por segurança. Se o comportamento antigo é explorável, digam isso, encurtem o período, e avisem todo chamador afetado diretamente em vez de confiar no changelog.
Preciso depreciar um campo, ou só endpoints inteiros? Campos, parâmetros, valores de enum, padrões e headers todos precisam do mesmo tratamento, porque cada um pode quebrar um chamador correto. Um campo removido é a depreciação mais comum e a mais frequentemente ignorada.
As afirmações técnicas deste artigo não foram revisadas de forma independente. Se algo estiver errado, avise a gente e vamos corrigir.