Como Evoluir as Tuas APIs Sem Quebrar Aplicações Móveis: Versionamento e Cabeçalhos Sunset (RFC 8594) Explicados
O Pesadelo das Alterações Destrutivas: Quando o Código Rápido Parte o Negócio
No início de um projeto, a equipa de programação move-se depressa: mudam-se nomes de tabelas na base de dados, convertem-se chaves de JSON de um estilo para outro e alteram-se respostas de endpoints numa tarde de trabalho.
Depois, o produto cresce e tem sucesso:
- Lanças aplicações nativas para iOS e Android. Milhares de clientes continuam a usar a versão antiga no telemóvel e não ativam as atualizações automáticas na loja.
- Empresas parceiras integram a faturação e os stocks diretamente na tua API pública.
- Sistemas de automação de terceiros consultam os teus dados a cada cinco minutos.
Numa sexta-feira de manhã, a equipa de backend publica uma melhoria e troca o campo "nome_cliente" por um objeto estruturado { "primeiro_nome": "...", "apelido": "..." }.
A QUEBRA DE SISTEMAS COM UMA ALTERAÇÃO DE API
- Atualização de Backend: { “nome_cliente” } → { “nome”: { “primeiro” } }
- Aplicação Móvel v1.2 (Cliente Antigo) Sistema B2B do Teu Maior Cliente
- Tenta ler: dados.nome_cliente
- Corre a sincronização bancária noturna
- Resultado: TypeError: undefined is not a Resultado: Erro 500 não tratado! function → A APP CRASHA! A faturação para! Clientes em fúria!
Para o teu frontend na web, a atualização correu lindamente. Mas para os utilizadores da aplicação móvel e para os teus parceiros de negócio, acabaste de deitar abaixo o software deles.
Tens de aceitar uma regra basilar da arquitetura de software: depois de uma API ser utilizada fora do teu repositório de código, nunca mais podes introduzir alterações destrutivas sem um ciclo formal de descontinuação.
Na nossa equipa desenhamos websites de alta performance e aplicações web que cumprem regras semânticas estritas de versionamento para garantir que o teu software evolui sem sobressaltos.
Estratégias de Versionamento: Caminho de URL vs. Negociação de Cabeçalhos
Antes de descontinuares uma funcionalidade, tens de decidir como os teus clientes solicitam versões diferentes da API:
VERSIONAMENTO POR URL VS CABEÇALHOS HTTP
- ESTRATÉGIA A: Versionamento no Caminho do URL
- GET /api/v1/faturas/1042 → Devolve o Formato Versão 1
- GET /api/v2/faturas/1042 → Devolve o Formato Versão 2
- Extremamente simples de testar • Duplica rotas no teu código
- Fácil de gerir e cachear na CDN • Cria URLs diferentes para a mesma entidade
- ESTRATÉGIA B: Negociação de Conteúdo por Cabeçalhos
- GET /api/faturas/1042
- Accept: application/vnd.empresa.v2+json
- Mantém um URL limpo e único • Mais difícil de testar no browser
- Máxima pureza na arquitetura REST• Exige lógica de encaminhamento no backend
1. Versionamento no URL (/api/v1/)
É o modelo mais comum e pragmático na internet. Embora puristas defendam que a versão não devia fazer parte do endereço físico do recurso, colocar a versão no caminho facilita o encaminhamento no Nginx e a configuração de regras de cache na Cloudflare.
2. Negociação por Cabeçalhos HTTP
Para arquiteturas corporativas complexas, preservas o mesmo URL canónico (https://api.empresa.com/clientes/42) e deixas o cliente pedir o esquema correto através de cabeçalhos HTTP:
GET /api/clientes/42 HTTP/2
Host: api.empresa.com
Accept: application/json; version=2
O Cabeçalho Sunset (RFC 8594): O Padrão Universal de Descontinuação
Como avisas centenas de sistemas automatizados de que uma rota da tua API vai deixar de existir?
Tradicionalmente, enviava-se um email em massa. O problema é que programadores ignoram emails e os servidores que correm em segundo plano não sabem ler correspondência.
Em 2019, o grupo de trabalho da IETF publicou a norma RFC 8594, criando o cabeçalho oficial Sunset.
CABEÇALHOS HTTP DAS NORMAS SUNSET E DEPRECATION
- A Aplicação do Teu Cliente GET /api/v1/pagamentos → O Teu Servidor
- A Aplicação do Teu Cliente → HTTP/2 200 OK
- Content-Type: application/json
- Deprecation: @1798761599
- Sunset: Thu, 31 Dec 2026 23:59:59 GMT
- Link: https://docs.api.com/migracao; rel=“sunset”
O Que Significa Cada Cabeçalho:
Sunset: <Data-HTTP>: Indica o segundo exato em que o endpoint será desligado para sempre.Deprecation: true: Sinaliza formalmente que o recurso está em fase de descontinuação e não deve ser usado em projetos novos.Link: <URL>; rel="sunset": Disponibiliza o link direto para a documentação técnica que ensina a migrar para a versão mais recente.
Quando o sistema do teu cliente consome estas respostas, consegue alertar automaticamente os programadores antes de a data expirar:
[Aviso de API] O endpoint /api/v1/pagamentos foi descontinuado e desliga em 31-12-2026.
Documentação de migração: https://docs.api.com/migracao
Como Implementar o Cabeçalho Sunset no Nginx e em Node.js
Podes aplicar estes cabeçalhos de forma muito simples no teu servidor web Nginx ou dentro do teu próprio código em Node.js.
1. Injetar Cabeçalhos Diretamente no Nginx
Se estás a descontinuar toda uma gama de rotas /api/v1/, podes colocar os cabeçalhos no proxy reverso:
# Configuração do Nginx: Avisa sobre o fim de vida da versão 1
location /api/v1/ {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
# Cabeçalho RFC 8594 Sunset (Data final: 31 de Dezembro de 2026)
add_header Sunset "Thu, 31 Dec 2026 23:59:59 GMT" always;
# Sinal de descontinuação ativa
add_header Deprecation "true" always;
# Link para o guia de migração técnica
add_header Link '<https://developer.empresa.com/migracao-v1-para-v2>; rel="sunset"' always;
}
2. Middleware para Node.js e Express/Fastify
Para teres controlo fino rota a rota na tua aplicação:
// middleware/descontinuacao.ts - Middleware RFC 8594
import { Request, Response, NextFunction } from 'express';
interface OpcoesDescontinuacao {
dataDesligamento: Date;
urlDocumentacao: string;
}
export function marcarComoDescontinuado(opcoes: OpcoesDescontinuacao) {
const dataSunsetHttp = opcoes.dataDesligamento.toUTCString();
const cabecalhoLink = `<${opcoes.urlDocumentacao}>; rel="sunset"`;
return (req: Request, res: Response, next: NextFunction) => {
// 1. Valida se a data limite já passou
if (Date.now() > opcoes.dataDesligamento.getTime()) {
res.status(410).json({
erro: "Gone",
mensagem: "Este serviço de API foi encerrado de forma definitiva.",
documentacao: opcoes.urlDocumentacao,
});
return;
}
// 2. Injeta os cabeçalhos das normas RFC 8594
res.setHeader('Sunset', dataSunsetHttp);
res.setHeader('Deprecation', 'true');
res.setHeader('Link', cabecalhoLink);
next();
};
}
Aplica este middleware nas tuas rotas legadas:
// rotas/v1/utilizadores.ts
import { Router } from 'express';
import { marcarComoDescontinuado } from './middleware/descontinuacao.js';
const router = Router();
// Define a data de encerramento da rota para 31 de Dezembro de 2026
router.get('/utilizadores', marcarComoDescontinuado({
dataDesligamento: new Date('2026-12-31T23:59:59Z'),
urlDocumentacao: 'https://docs.empresa.com/api/migracao-utilizadores-v2'
}), (req, res) => {
res.json({ utilizadores: [{ id: 1, nomeAntigo: "Maria" }] });
});
export default router;
O Dia do Encerramento: Porque Deves Devolver HTTP 410 Gone
O que acontece quando chega o dia 31 de Dezembro de 2026 e desligas o serviço antigo?
Muitas equipas cometem o erro de devolver o código 404 Not Found. O código 404 diz apenas que a página não foi encontrada agora, dando a entender que o utilizador pode ter-se enganado a escrever ou que o serviço pode voltar amanhã.
O código de estado correto segundo as normas da web é o 410 Gone.
O ENCERRAMENTO DEFINITIVO COM HTTP 410 GONE
- Cliente da App GET /api/v1/utilizadores → Servidor
- Cliente da App → HTTP/2 410 Gone
- Content-Type: application/problem+json
- “type”: “https://erros.empresa.com/api-encerrada”, “title”: “Serviço Descontinuado Definitivamente”, “status”: 410, “detail”: “A versão v1 foi desligada em 2026-12-31.”, “instance”: “/api/v1/utilizadores”
O código 410 Gone informa de forma permanente motores de busca, proxies de rede e bibliotecas de integração de que a rota foi apagada de propósito e nunca mais voltará. Isto faz com que os sistemas parem de tentar fazer pedidos repetidos desnecessários.
Ao aplicares regras rigorosas de versionamento e cabeçalhos Sunset RFC 8594, ganhas a liberdade de refatorar o teu código sem arriscares os negócios dos teus parceiros. Guiando a tua infraestrutura pelo nosso princípio de anti-over-engineering, constróis APIs sólidas, profissionais e preparadas para durar. Podes encontrar mais padrões de integração no GitHub para padronizares as tuas rotas em minutos.
No terreno, em conjunto com a experiência acumulada na Webxtek Studio, aplicamos exatamente estes padrões operacionais em setores exigentes como saas empresarial b2b e especialistas em devops e arquitetura cloud. Quando alinhas a tua estrutura através de websites de alta performance e anti-over-engineering, transformas boas práticas técnicas numa vantagem competitiva real e mensurável para o teu negócio.
[+] [ INDEX_DIRECTORY ] 18 tópicos ▼
- O Pesadelo das Alterações Destrutivas: Quando o Código Rápido Parte o Negócio
- Estratégias de Versionamento: Caminho de URL vs. Negociação de Cabeçalhos
- 1. Versionamento no URL (/api/v1/)
- 2. Negociação por Cabeçalhos HTTP
- O Cabeçalho Sunset (RFC 8594): O Padrão Universal de Descontinuação
- O Que Significa Cada Cabeçalho:
- Como Implementar o Cabeçalho Sunset no Nginx e em Node.js
- 1. Injetar Cabeçalhos Diretamente no Nginx
- 2. Middleware para Node.js e Express/Fastify
- O Dia do Encerramento: Porque Deves Devolver HTTP 410 Gone
- Autor
- Perguntas Frequentes
- O que é o cabeçalho HTTP Sunset definido na norma RFC 8594?
- Qual é a diferença entre versionar por caminho de URL (/v1/users) ou por cabeçalhos HTTP?
- Como deve a tua API responder quando a data do Sunset tiver passado?
- Como é que as bibliotecas de cliente lêem estes cabeçalhos de descontinuação?
- Nós Relacionados
- Sequência do Caminho
Perguntas Frequentes
O que é o cabeçalho HTTP Sunset definido na norma RFC 8594?
A norma RFC 8594 define o cabeçalho HTTP `Sunset`, que informa os clientes da data e hora exatas em que um determinado endpoint ou serviço deixará de funcionar de forma definitiva. Formatado segundo as normas de data HTTP (`Sunset: Wed, 31 Dec 2026 23:59:59 GMT`), permite a sistemas automatizados ler e antecipar o fim de vida de uma API sem intervenção humana.
Qual é a diferença entre versionar por caminho de URL (/v1/users) ou por cabeçalhos HTTP?
Versionar por URL (`/v1/users` e `/v2/users`) cria rotas visíveis distintas, sendo fácil de ler e configurar em proxies reversos. Versionar por cabeçalhos (`Accept: application/vnd.empresa.v2+json`) preserva a identidade única do URL da entidade segundo os princípios puros de REST, permitindo ao servidor negociar o formato de resposta internamente.
Como deve a tua API responder quando a data do Sunset tiver passado?
Assim que a data limite do cabeçalho Sunset expira, o teu servidor deve responder permanentemente com o código de estado HTTP `410 Gone`. Este código informa o cliente de que o recurso foi descontinuado propositadamente e nunca mais voltará a estar acessível.
Como é que as bibliotecas de cliente lêem estes cabeçalhos de descontinuação?
As bibliotecas de ligação modernas e gateways de API verificam a presença dos cabeçalhos `Deprecation: true` e `Sunset: ` em cada resposta HTTP. Se existirem, os sistemas registam avisos estruturados nos logs centrais da empresa, alertando os engenheiros para atualizarem o código antes do desligamento definitivo.
[ RELATED_NODES ]
> INICIAR_PROJETO
Precisa de um website que transmita confiança, apareça na pesquisa e dê mais força à sua presença digital? Comece a conversa aqui.