Fluxo requisição–resposta: o que realmente acontece quando você “chama uma API”
Em testes de API, entender o caminho completo de uma requisição REST ajuda a formular hipóteses mais precisas: onde um erro pode surgir, quais camadas podem alterar a resposta e quais evidências coletar (status, headers, payload, tempo, logs/correlation id). Na prática, uma chamada percorre etapas típicas: cliente → gateway/proxy → serviço (API) → banco/cache e volta no sentido inverso.
1) Cliente (consumer)
É quem monta a requisição HTTP: método, URL, headers, query string e body. Para testes, o cliente é seu ponto de controle: você varia entradas para observar mudanças na saída.
- O que observar: método correto (GET/POST/PUT/PATCH/DELETE), serialização do body (JSON válido), headers obrigatórios (ex.: Authorization, Content-Type), encoding, e consistência de parâmetros.
- Hipóteses de teste: “Se eu omitir um header obrigatório, a API rejeita?”, “Se eu enviar um campo extra, é ignorado ou causa erro?”, “Se eu trocar o tipo (string vs number), a validação pega?”
2) Gateway / Proxy (API Gateway, reverse proxy, WAF)
Camada intermediária que pode autenticar, aplicar rate limit, roteamento, transformação de headers, cache, e bloquear padrões suspeitos. Em testes, isso explica por que o comportamento pode mudar sem alteração no serviço.
- O que observar: headers adicionados/removidos (ex.: X-Request-Id), respostas de bloqueio, limites de requisição, redirecionamentos, e diferenças entre ambientes.
- Hipóteses de teste: “Após N chamadas, recebo bloqueio?”, “Um header específico altera o roteamento?”, “O gateway está cacheando respostas que deveriam refletir mudanças?”
3) Serviço (API REST)
Implementa regras de negócio e validações. Aqui você valida contrato: campos obrigatórios, formatos, regras, e consistência entre recursos.
- O que observar: validação de schema, mensagens de erro, campos calculados, idempotência, e consistência de dados retornados.
- Hipóteses de teste: “Se eu enviar um estado inválido, a API recusa?”, “Atualizações parciais preservam campos não enviados?”, “A resposta inclui apenas o que o contrato prevê?”
4) Banco de dados e Cache
O serviço consulta e persiste dados. Caches (Redis, CDN, cache do gateway) podem devolver respostas sem tocar no banco. Para testes, isso impacta cenários de consistência, invalidação e observabilidade.
- Ouça o áudio com a tela desligada
- Ganhe Certificado após a conclusão
- + de 5000 cursos para você explorar!
Baixar o aplicativo
- O que observar: tempo de resposta (cache vs banco), headers de cache, consistência após escrita, e efeitos de concorrência.
- Hipóteses de teste: “Após atualizar um recurso, um GET imediato reflete a mudança?”, “Há stale data por cache?”, “A API retorna o mesmo resultado em chamadas repetidas?”
Recursos, endpoints e rotas: como mapear o que testar
Em REST, você testa principalmente recursos (entidades do domínio) acessados por endpoints (rotas). Um recurso costuma ser representado por um caminho (path) e identificado por um id.
Recursos e coleções
- Coleção:
/users(lista/criação) - Item:
/users/{userId}(consulta/atualização/remoção) - Sub-recurso:
/users/{userId}/orders(pedidos de um usuário)
Para testes, isso sugere uma matriz mínima: operações na coleção (listar/criar) e no item (buscar/alterar/remover), além de relações (sub-recursos).
Parâmetros: path, query e headers
- Path params (identificação):
/users/123 - Query string (filtro/paginação/ordenação):
/users?status=active&page=2&limit=20&sort=-createdAt - Headers (contexto):
Authorization,Accept,Content-Type,If-None-Match
Em testes, cada tipo de parâmetro tem riscos típicos: path inválido (id inexistente), query com combinações inesperadas (filtros conflitantes), headers ausentes ou incorretos (negociação de conteúdo, autenticação).
Representações (JSON): o que validar além de “retornou 200”
REST trafega representações do recurso, frequentemente em JSON. Testar JSON não é só checar campos: é validar estrutura, tipos, restrições e semântica.
Checklist prático para payload JSON
- Campos obrigatórios: ausentes devem gerar erro ou default explícito.
- Tipos: número vs string, boolean, arrays, objetos aninhados.
- Formato: datas (ISO-8601), e-mails, enums.
- Campos somente leitura: não devem ser aceitos em criação/atualização (ou devem ser ignorados de forma consistente).
- Campos desconhecidos: a API rejeita ou ignora? Defina expectativa e teste.
- Ordem de campos: não deve importar.
- Nulos e vazios: diferença entre
null,"",[], campo ausente.
Exemplo de representação
{ "id": "u_123", "name": "Ana", "email": "ana@example.com", "status": "active", "createdAt": "2026-01-26T10:15:00Z" }Hipóteses de teste: “status aceita apenas valores do enum?”, “createdAt é sempre ISO-8601?”, “id é imutável?”
Stateless na validação: como isso muda seus testes
Stateless significa que cada requisição deve conter o contexto necessário para ser processada: autenticação, parâmetros e dados. O servidor não deve depender de “memória de sessão” para responder corretamente (embora possa haver tokens e caches).
Implicações de teste
- Repetibilidade: a mesma requisição (mesma entrada) deve produzir resposta consistente, exceto por campos naturalmente variáveis (timestamps, ids gerados).
- Ordem de execução: testes devem minimizar dependência de sequência (ou explicitar pré-condições).
- Autorização por request: validar que sem token/credencial a API não “lembra” do cliente.
Passo a passo: testando stateless com autenticação
- Faça uma chamada autenticada e capture um identificador de rastreio se existir (ex.:
X-Request-Id). - Repita a chamada sem o header
Authorization. - Compare: a segunda deve falhar de forma consistente (mesma regra), sem “herdar” contexto da primeira.
- Repita a chamada com token inválido/expirado e observe se a falha é coerente.
Cacheabilidade: quando o “mesmo GET” não deveria bater no serviço
Algumas respostas podem ser cacheadas para performance. Isso afeta testes porque você pode receber uma resposta “antiga” mesmo após uma atualização, ou pode não conseguir reproduzir um bug porque o cache mascara o comportamento real.
O que validar em cache
- Headers de cache: presença e coerência de
Cache-Control,ETag,Last-Modified(quando aplicável). - Invalidação: após
POST/PUT/PATCH/DELETE, umGETdeve refletir a mudança dentro do SLA esperado. - Variação: respostas cacheadas devem variar corretamente por parâmetros relevantes (query, headers como
Accept-Languagese usado).
Passo a passo: hipótese de stale cache após atualização
- Faça
GET /products/10e guarde o payload e headers. - Faça
PATCH /products/10alterando um campo (ex.:price). - Faça
GET /products/10imediatamente e compare o campo alterado. - Se vier o valor antigo, investigue: há cache no gateway? há TTL? a invalidação depende de evento assíncrono?
Exemplos concretos de chamadas REST e o que observar em cada etapa
Exemplo 1: Listagem com query string (filtros e paginação)
Requisição
GET https://api.exemplo.com/v1/users?status=active&page=2&limit=20&sort=-createdAt HTTP/1.1 Accept: application/json Authorization: Bearer <token>O que observar
- Query: combinações inválidas (ex.:
limit=0,page=-1,sortpor campo inexistente). - Contrato: estrutura da lista (array), metadados de paginação (se existirem), e estabilidade da ordenação.
- Gateway: rate limit em endpoints de listagem; cache por query.
- Hipóteses: “
statusdesconhecido retorna vazio ou erro?”, “página fora do range retorna vazio ou erro?”
Exemplo 2: Criação com body JSON (validação de campos)
Requisição
POST https://api.exemplo.com/v1/users HTTP/1.1 Content-Type: application/json Accept: application/json Authorization: Bearer <token> { "name": "Ana", "email": "ana@example.com", "status": "active" }O que observar
- Body: campos obrigatórios ausentes, tipos errados, enum inválido.
- Somente leitura: tentar enviar
idoucreatedAte verificar comportamento esperado. - Persistência: após criar, fazer
GETno recurso criado e validar consistência. - Hipóteses: “e-mail duplicado é bloqueado?”, “nome vazio é aceito?”, “campos extras são ignorados ou rejeitados?”
Exemplo 3: Consulta por id (path param) e casos de inexistência
Requisição
GET https://api.exemplo.com/v1/users/u_123 HTTP/1.1 Accept: application/json Authorization: Bearer <token>O que observar
- Path param: formato do id (ex.:
u_123vs123), caracteres inválidos, tamanho máximo. - Representação: campos retornados, tipos, e se dados sensíveis não aparecem.
- Cache: chamadas repetidas; headers de cache se aplicável.
- Hipóteses: “id inexistente retorna erro consistente?”, “id malformado é validado antes de ir ao banco?”
Exemplo 4: Atualização parcial (PATCH) e efeitos colaterais
Requisição
PATCH https://api.exemplo.com/v1/users/u_123 HTTP/1.1 Content-Type: application/json Accept: application/json Authorization: Bearer <token> { "status": "inactive" }O que observar
- Parcialidade: campos não enviados permanecem iguais.
- Regras: transições de estado permitidas (active → inactive) e proibidas.
- Concorrência: duas atualizações seguidas; verificar se a última vence e se há proteção contra overwrite.
- Cache: se o GET subsequente reflete a mudança.
Exemplo 5: Endpoint com múltiplos parâmetros (path + query) para sub-recurso
Requisição
GET https://api.exemplo.com/v1/users/u_123/orders?from=2026-01-01&to=2026-01-31&status=paid HTTP/1.1 Accept: application/json Authorization: Bearer <token>O que observar
- Validação cruzada:
frommaior queto, datas inválidas, timezone. - Escopo: garantir que retorna apenas pedidos do usuário do path.
- Performance: filtros amplos podem pressionar banco; observar tempo e paginação.
- Hipóteses: “sem filtros retorna tudo (com paginação)?”, “status desconhecido retorna vazio ou erro?”
Como transformar o fluxo em hipóteses de teste (mapa rápido)
| Camada | Risco comum | Hipótese de teste | Evidência a coletar |
|---|---|---|---|
| Cliente | Serialização/headers incorretos | “Sem Content-Type, o serviço rejeita?” | Resposta, headers, mensagem de erro |
| Gateway/Proxy | Rate limit/bloqueio/cache | “Após 100 req/min, ocorre bloqueio?” | Headers de limite, status, tempo |
| Serviço | Validação e regra de negócio | “Enum inválido é recusado?” | Payload de erro, campo apontado |
| Banco/Cache | Consistência e invalidação | “Após PATCH, GET reflete mudança?” | Comparação de payloads, timestamps |