Home > Blog > Desenvolvimento Web
Desenvolvimento Web
JavaScript
Programação

API Versioning no Node.js: evolua sem quebrar clientes

Atualizado em: 24 de outubro de 2026

Terminal Linux usado em desenvolvimento e administração de aplicações Node.js

API Versioning no Node.js organiza mudanças incompatíveis sem quebrar imediatamente clientes existentes. Uma API evolui: campos são adicionados, regras mudam, formatos de erro são corrigidos e operações antigas precisam ser aposentadas. O versionamento define como essas mudanças são comunicadas e por quanto tempo versões diferentes coexistem.

Nem toda alteração exige uma nova versão. Adicionar um campo opcional ou um novo endpoint geralmente é compatível. Renomear propriedades, mudar significado, tornar campo obrigatório ou alterar códigos de status pode quebrar consumidores e precisa de estratégia explícita.

O que é breaking change?

  • remover ou renomear campo;
  • mudar tipo de dado;
  • alterar semântica de uma propriedade;
  • tornar parâmetro obrigatório;
  • remover valor de enum;
  • alterar autenticação;
  • trocar códigos de erro esperados;
  • reduzir limites ou comportamento sem transição.

Versionamento na URL

GET /v1/orders/123
GET /v2/orders/123

É simples de entender, documentar e rotear. A versão aparece em logs, caches e métricas. A desvantagem é incentivar duplicação de controllers quando a equipe copia toda a API.

app.use('/v1', createV1Router(dependencies));
app.use('/v2', createV2Router(dependencies));

Compartilhe casos de uso e domínio. A versão deve ficar principalmente nos adapters de entrada e nos DTOs.

Versionamento por header

Accept: application/vnd.example.order.v2+json

O URI permanece estável e o formato é negociado. Porém, debugging e testes ficam menos óbvios, e caches precisam considerar Vary: Accept.

Header próprio

X-API-Version: 2026-10-01

É fácil de implementar, mas headers proprietários exigem documentação e suporte cuidadoso em proxies e SDKs.

Versões por data

Datas comunicam uma fotografia do contrato e funcionam bem quando mudanças são agrupadas.

API-Version: 2026-10-01

Não use a data como desculpa para mudanças frequentes sem migração. O cliente ainda precisa de prazo, documentação e testes.

Escolhendo uma estratégia

Para APIs públicas, URL ou header explícito são previsíveis. Para APIs internas, pode ser melhor evoluir contratos de forma compatível e usar versionamento apenas quando necessário. Evite misturar várias estratégias no mesmo produto.

Separando contrato e domínio

function toOrderV1(order) {
  return {
    id: order.id,
    total: order.totalCents / 100
  };
}

function toOrderV2(order) {
  return {
    id: order.id,
    amount: {
      value: order.totalCents,
      currency: order.currency
    }
  };
}

O domínio continua único. Cada versão possui serializers e validators próprios.

Validação por versão

const schemas = {
  v1: orderRequestV1,
  v2: orderRequestV2
};

function validateRequest(version, body) {
  const schema = schemas[version];
  if (!schema) throw new Error('Versão não suportada');
  return schema.parse(body);
}

Consulte JSON Schema no Node.js.

OpenAPI por versão

Mantenha uma especificação para cada contrato suportado ou gere documentos a partir de componentes compartilhados.

openapi-v1.yaml
openapi-v2.yaml

O CI pode detectar breaking changes antes do merge. Veja OpenAPI no Node.js.

Banco de dados

Não associe versão da API diretamente a uma versão rígida do schema. Durante a transição, o banco deve suportar leitores e escritores antigos e novos.

Use expand and contract:

  1. adicione nova coluna ou estrutura;
  2. publique código que entende ambos os formatos;
  3. faça backfill;
  4. migre clientes;
  5. pare de escrever o formato antigo;
  6. remova a estrutura legada depois do prazo.

Consulte Database Migrations no Node.js.

Depreciação

Uma versão antiga precisa de política clara:

  • data de anúncio;
  • data de fim de suporte;
  • guia de migração;
  • diferenças de contrato;
  • canal de suporte;
  • métricas de uso.

Headers podem informar depreciação e links para documentação, conforme padrões adotados pela organização.

Roteamento

function resolveVersion(req) {
  const raw = req.headers['api-version'] ?? '2026-01-01';
  const allowed = new Set(['2026-01-01', '2026-10-01']);

  if (!allowed.has(raw)) {
    const error = new Error('Versão não suportada');
    error.statusCode = 400;
    throw error;
  }

  return raw;
}

Nunca carregue módulos ou execute código com base em string arbitrária de versão.

Versão padrão

Uma versão implícita facilita o início, mas pode impedir clientes de perceber mudanças. Para APIs críticas, exija versão explícita ou congele a versão padrão por longos períodos.

Erros consistentes

Mesmo quando payloads de sucesso evoluem, preserve uma estrutura de erro previsível. Mudanças em códigos e campos de erro também afetam integrações.

Idempotência entre versões

Uma chave idempotente deve identificar a mesma intenção, mas o fingerprint precisa considerar a versão e o corpo normalizado.

const fingerprint = hash({
  version,
  method: req.method,
  path: req.route.path,
  body: normalizedBody
});

Veja Idempotency Keys no Node.js.

Cache

Se a versão vem por header, inclua o header em Vary e na chave do cache. Uma resposta v2 não pode ser servida para um cliente v1.

res.setHeader('Vary', 'API-Version, Accept-Encoding');

Eventos e webhooks

Eventos também são contratos e precisam de versão no tipo ou envelope.

{
  "type": "order.created.v2",
  "id": "evt-1",
  "data": { }
}

Não altere silenciosamente o significado de um evento existente.

SDKs

SDKs podem fixar uma versão por release. Documente quais versões da API cada SDK suporta e mantenha testes de contrato.

Testes

  • requests válidos de cada versão;
  • versão ausente;
  • versão desconhecida;
  • serialização de respostas;
  • autorização igual entre versões;
  • cache separado;
  • migração de banco compatível;
  • clientes antigos durante rollout;
  • documentação sincronizada.

Observabilidade

Inclua versão em logs, traces e métricas. Monitore tráfego, erros e latência por versão. Antes de remover uma versão, confirme que uso residual é conhecido.

Erros comuns

  • criar versão nova para qualquer mudança;
  • duplicar todo o código;
  • mudar semântica sem versionar;
  • não medir clientes antigos;
  • remover versão sem prazo;
  • esquecer cache e webhooks;
  • acoplar domínio à versão;
  • não testar banco durante coexistência.

Checklist

  • breaking changes definidos;
  • estratégia única escolhida;
  • DTOs por versão;
  • domínio compartilhado;
  • OpenAPI atualizado;
  • CI detecta incompatibilidades;
  • depreciação documentada;
  • métricas por versão;
  • cache isolado;
  • migration compatível.

Conclusão

API Versioning no Node.js é uma disciplina de compatibilidade, não apenas um prefixo na URL. O objetivo é permitir evolução previsível enquanto clientes migram com segurança.

Versione somente mudanças incompatíveis, mantenha domínio compartilhado, meça uso e ofereça uma janela de depreciação. Com contratos testados e migrations compatíveis, versões coexistem sem transformar a aplicação em várias bases de código independentes.

Consulte a especificação OpenAPI e o RFC de semântica HTTP.

10 melhores cursos de programação em 2026

Descubra os melhores cursos de programação. Aprenda a escolher o curso ideal para iniciar ou avançar na carreira de desenvolvedor

POSTS RELACIONADOS

Ver todos

Seta para a direita