Headers e negociação de conteúdo em testes de API (Content-Type e Accept)

Capítulo 3

Tempo estimado de leitura: 10 minutos

+ Exercício

Por que headers importam em testes de API

Headers são metadados da requisição e da resposta. Eles controlam como o servidor deve interpretar o corpo (payload), qual formato o cliente aceita receber, como autenticar, como cachear, como correlacionar chamadas e como aplicar regras específicas do domínio. Em testes de API, validar headers é tão importante quanto validar o body, porque muitos comportamentos (sucesso, erro, cache, compatibilidade) dependem deles.

O que testar em headers (checklist rápido)

  • Requisição: Content-Type, Accept, Authorization, User-Agent, Cache-Control, If-None-Match, Correlation-Id e headers customizados.
  • Resposta: Content-Type (incluindo charset), ETag, Cache-Control, Vary, WWW-Authenticate (quando aplicável), e eco/propagação de correlação (quando o sistema define esse contrato).

Content-Type: como o servidor interpreta o corpo

Content-Type descreve o tipo de mídia do corpo enviado na requisição (e também aparece na resposta para indicar o formato retornado). Em testes, ele é crucial para validar parsing, validação e erros de mídia.

Casos comuns de Content-Type

  • application/json: payload JSON.
  • application/xml: payload XML.
  • application/x-www-form-urlencoded: formulário simples.
  • multipart/form-data: upload de arquivos e campos.
  • text/plain: texto puro.

Charset e encoding (o que validar)

É comum ver Content-Type: application/json; charset=utf-8. O charset define a codificação de caracteres (por exemplo, UTF-8). Em APIs modernas, UTF-8 é o padrão de fato, mas seu teste deve garantir consistência quando o contrato exige.

  • Validar resposta: o Content-Type retornado deve corresponder ao formato real do body (ex.: JSON válido quando diz application/json).
  • Validar caracteres: strings com acentos/emoji devem chegar e voltar corretamente (ex.: “ação”, “café”, “São Paulo”).
  • Encoding de transporte: compressão como Content-Encoding: gzip pode existir; em testes automatizados, verifique se o cliente lida com isso e se o servidor anuncia corretamente.

Erro 415 (Unsupported Media Type): quando o Content-Type é inválido

O status 415 ocorre quando o servidor não suporta o tipo de mídia enviado (ou não consegue processar o corpo com aquele Content-Type).

O que checar no teste de 415:

Continue em nosso aplicativo e ...
  • Ouça o áudio com a tela desligada
  • Ganhe Certificado após a conclusão
  • + de 5000 cursos para você explorar!
ou continue lendo abaixo...
Download App

Baixar o aplicativo

  • O status code é 415.
  • A resposta contém mensagem/estrutura de erro conforme contrato (por exemplo, code, message, details).
  • Não há efeitos colaterais (nenhum recurso criado/alterado).
# Exemplo: enviando JSON, mas declarando text/plain (provável 415 ou 400, dependendo da API) curl -i -X POST https://api.exemplo.com/pedidos -H "Content-Type: text/plain" -H "Accept: application/json" -d '{"item":"cafe","qtd":1}'

Observação: algumas APIs retornam 400 quando o body não é parseável; outras retornam 415 quando o tipo de mídia é o problema. Seu teste deve refletir o contrato esperado para aquele endpoint.

Accept: o que o cliente quer receber (content negotiation)

Accept indica quais tipos de mídia o cliente aceita na resposta. Isso habilita negociação de conteúdo (content negotiation): o servidor escolhe um formato compatível com o que o cliente pediu e com o que ele consegue produzir.

Exemplos de Accept

  • Accept: application/json (quero JSON)
  • Accept: application/xml (quero XML)
  • Accept: application/json, application/xml;q=0.9 (prefiro JSON, aceito XML com prioridade menor)
  • Accept: */* (aceito qualquer coisa)

Como validar a negociação na prática

  • Se o cliente envia Accept: application/json, a resposta deve vir com Content-Type compatível (ex.: application/json).
  • Se o cliente envia múltiplos tipos com q (quality), o servidor deve escolher o mais adequado (conforme implementação/contrato).
  • Se o servidor não consegue produzir nenhum tipo aceito, deve retornar 406 Not Acceptable.

Erro 406 (Not Acceptable): quando não há formato compatível

406 ocorre quando o servidor não consegue responder em nenhum dos formatos solicitados em Accept.

# Exemplo: pedindo um formato que a API não suporta curl -i https://api.exemplo.com/pedidos/123 -H "Accept: application/pdf"

O que checar no teste de 406:

  • Status code 406.
  • Resposta de erro com Content-Type consistente (muitas APIs retornam erros em JSON mesmo quando o Accept é inválido; isso deve estar documentado/contratado).
  • Mensagem clara indicando formatos suportados (quando aplicável).

Authorization: autenticação e autorização via header

Authorization carrega credenciais (por exemplo, token). Em testes, você valida tanto o comportamento de autenticação (credencial válida/inválida/ausente) quanto a autorização (permissões).

Padrões comuns

  • Authorization: Bearer <token>
  • Authorization: Basic <base64(user:pass)>

Casos de teste essenciais

  • Sem header: deve retornar 401 (ou conforme contrato).
  • Token inválido/expirado: 401.
  • Token válido sem permissão: 403.
  • Formato malformado (ex.: “Bearer” sem token): erro consistente (frequentemente 401).
# Sem Authorization curl -i https://api.exemplo.com/pedidos/123 -H "Accept: application/json" # Token inválido curl -i https://api.exemplo.com/pedidos/123 -H "Accept: application/json" -H "Authorization: Bearer token_invalido"

User-Agent: identificação do cliente e comportamento condicional

User-Agent identifica o cliente (biblioteca, app, versão). Algumas APIs aplicam regras por User-Agent (bloqueio, rate limit diferenciado, compatibilidade). Em testes, isso é útil para reproduzir bugs específicos de clientes e validar políticas.

O que testar

  • Se a API exige User-Agent, ausência deve gerar erro claro (não é comum, mas existe).
  • Se há comportamento diferenciado por versão, valide respostas para User-Agents distintos.
curl -i https://api.exemplo.com/pedidos/123 -H "Accept: application/json" -H "User-Agent: MeuClienteTeste/1.0"

Cache-Control, ETag e If-None-Match: cache e respostas condicionais

Headers de cache impactam performance e consistência. Em testes, você valida se o servidor anuncia cache corretamente e se respeita requisições condicionais.

Cache-Control (resposta)

  • Cache-Control: no-store: não deve ser armazenado.
  • Cache-Control: no-cache: pode armazenar, mas deve revalidar.
  • Cache-Control: max-age=60: pode usar cache por 60s.

ETag e If-None-Match (revalidação)

ETag é um identificador da versão do recurso. O cliente pode enviar If-None-Match com a ETag recebida; se nada mudou, o servidor responde 304 Not Modified sem body.

Passo a passo: testando ETag/If-None-Match

  1. Faça um GET no recurso e capture o header ETag.
  2. Repita o GET enviando If-None-Match com o valor capturado.
  3. Valide que a resposta é 304 (quando não houve mudança) e que não há body (ou body vazio, conforme implementação).
  4. Altere o recurso (por uma operação que mude o conteúdo) e repita o GET com a ETag antiga; agora deve retornar 200 com nova ETag.
# 1) Capturar ETag curl -i https://api.exemplo.com/pedidos/123 -H "Accept: application/json" # suponha que veio: ETag: "abc123" # 2) Requisição condicional curl -i https://api.exemplo.com/pedidos/123 -H "Accept: application/json" -H "If-None-Match: \"abc123\""

O que validar:

  • Quando retorna 304, headers relevantes ainda podem vir (ex.: ETag, Cache-Control).
  • Quando retorna 200, o body corresponde ao estado atual e a ETag muda quando o recurso muda.

Correlation-Id: rastreabilidade ponta a ponta

Correlation-Id (ou variações como X-Correlation-Id) ajuda a rastrear uma requisição em logs distribuídos. Em testes, ele é útil para depuração e também pode fazer parte do contrato (por exemplo, o servidor deve ecoar o mesmo ID).

O que testar

  • Enviar um Correlation-Id e validar se a resposta ecoa o mesmo valor (quando definido).
  • Quando não enviado, validar se o servidor gera um e retorna (quando definido).
  • Formato: UUID, string alfanumérica, tamanho máximo.
curl -i https://api.exemplo.com/pedidos/123 -H "Accept: application/json" -H "Correlation-Id: 3f2a2c2e-7a7b-4b2f-9c2f-4c9b3a1c2d10"

Headers customizados: regras de negócio e compatibilidade

APIs podem definir headers próprios para versionamento, idempotência, tenant, região, etc. Exemplos: X-Api-Version, Idempotency-Key, X-Tenant-Id. Em testes, trate-os como parte do contrato: presença, formato, obrigatoriedade e efeitos.

Exemplo: versionamento por header

curl -i https://api.exemplo.com/pedidos/123 -H "Accept: application/json" -H "X-Api-Version: 2"

Casos de teste:

  • Versão suportada: resposta conforme schema esperado.
  • Versão não suportada: erro consistente (frequentemente 400 ou 406, conforme contrato).
  • Ausência do header quando obrigatório: erro claro.

Exercícios práticos: variações de headers e casos negativos

Exercício 1: matriz de Content-Type vs body

Objetivo: observar como o servidor diferencia “tipo de mídia não suportado” (415) de “payload inválido” (400).

CasoContent-TypeBody enviadoEsperado
Aapplication/jsonJSON válido2xx
Bapplication/jsonJSON inválido400 (ou contrato)
Ctext/plainJSON válido415 (ou contrato)
D(sem Content-Type)JSON válido415/400 (ou contrato)
# Caso B: JSON inválido curl -i -X POST https://api.exemplo.com/pedidos -H "Content-Type: application/json" -H "Accept: application/json" -d '{"item": "cafe", "qtd": }' # Caso C: tipo de mídia incompatível curl -i -X POST https://api.exemplo.com/pedidos -H "Content-Type: text/plain" -H "Accept: application/json" -d '{"item":"cafe","qtd":1}'

Exercício 2: negociação com Accept e validação de 406

Objetivo: confirmar os formatos suportados e o comportamento quando o cliente pede algo impossível.

  1. Chame o endpoint com Accept: application/json e registre o Content-Type da resposta.
  2. Repita com Accept: application/xml (se a API suportar) e compare.
  3. Envie Accept: application/pdf e valide 406.
  4. Envie Accept: */* e valide que retorna um formato padrão (geralmente JSON).
curl -i https://api.exemplo.com/pedidos/123 -H "Accept: application/json" curl -i https://api.exemplo.com/pedidos/123 -H "Accept: application/pdf" curl -i https://api.exemplo.com/pedidos/123 -H "Accept: */*"

Exercício 3: charset e caracteres especiais

Objetivo: validar que o servidor interpreta e devolve caracteres corretamente.

  1. Envie um payload com acentos e caracteres especiais.
  2. Valide que o valor persistido/retornado é idêntico.
  3. Valide o Content-Type da resposta com charset esperado (quando aplicável).
curl -i -X POST https://api.exemplo.com/clientes -H "Content-Type: application/json; charset=utf-8" -H "Accept: application/json" -d '{"nome":"João da Silva","cidade":"São Paulo","observacao":"café"}'

Exercício 4: Authorization negativo e mensagens consistentes

Objetivo: garantir que falhas de autenticação/autorização são previsíveis e não vazam detalhes sensíveis.

  • Sem Authorization → validar 401 e, se houver, WWW-Authenticate.
  • Com token inválido → validar 401.
  • Com token válido sem permissão → validar 403.
curl -i https://api.exemplo.com/admin/relatorios -H "Accept: application/json" curl -i https://api.exemplo.com/admin/relatorios -H "Accept: application/json" -H "Authorization: Bearer invalido"

Exercício 5: ETag/If-None-Match e 304

Objetivo: validar cache condicional e ausência de body em 304.

  1. Faça GET e capture ETag.
  2. Reenvie GET com If-None-Match e valide 304.
  3. Altere o recurso e valide que volta a responder 200 com nova ETag.

Exercício 6: Correlation-Id e propagação

Objetivo: validar rastreabilidade.

  1. Envie um Correlation-Id fixo.
  2. Valide se a resposta contém o mesmo header e valor (quando contratual).
  3. Envie requests concorrentes com IDs diferentes e valide que não há mistura.
curl -i https://api.exemplo.com/pedidos/123 -H "Accept: application/json" -H "Correlation-Id: teste-req-001" curl -i https://api.exemplo.com/pedidos/123 -H "Accept: application/json" -H "Correlation-Id: teste-req-002"

Exercício 7: headers customizados (casos negativos)

Objetivo: validar robustez do contrato para headers específicos do domínio.

  • Header obrigatório ausente (ex.: X-Tenant-Id) → erro esperado.
  • Header com formato inválido (ex.: tamanho excedido, caracteres proibidos) → erro esperado.
  • Header com valor desconhecido (ex.: tenant inexistente) → erro esperado (frequentemente 404 ou 403, conforme contrato).
curl -i https://api.exemplo.com/pedidos/123 -H "Accept: application/json" -H "X-Tenant-Id: " curl -i https://api.exemplo.com/pedidos/123 -H "Accept: application/json" -H "X-Tenant-Id: tenant_inexistente"

Agora responda o exercício sobre o conteúdo:

Em um teste de negociação de conteúdo, o cliente envia Accept com um formato que a API não consegue produzir. Qual comportamento é esperado?

Você acertou! Parabéns, agora siga para a próxima página

Você errou! Tente novamente.

O header Accept define quais formatos o cliente aceita na resposta. Se o servidor não consegue produzir nenhum dos tipos aceitos, o resultado esperado é 406 Not Acceptable.

Próximo capitúlo

Autenticação e autorização em testes de API: validações essenciais

Arrow Right Icon
Capa do Ebook gratuito Testes de API: Conceitos Essenciais (REST, HTTP, Status Codes e Contratos)
20%

Testes de API: Conceitos Essenciais (REST, HTTP, Status Codes e Contratos)

Novo curso

15 páginas

Baixe o app para ganhar Certificação grátis e ouvir os cursos em background, mesmo com a tela desligada.