O problema que ele resolve
Antes do QUERY, existia uma lacuna entre GET e POST
para operações de consulta com filtros complexos.
GET é seguro, idempotente e cacheável, mas tecnicamente não define
semântica para um corpo de requisição — na prática clientes, servidores e proxies podem
ignorá-lo ou rejeitá-lo. Por isso filtros acabam indo na URL (?city=Berlin&limit=50),
o que traz limites de tamanho, parâmetros vazando em logs/proxies, e URLs semanticamente
iguais (?a=1&b=2 vs ?b=2&a=1) sendo tratadas como cache
entries diferentes.
POST aceita corpo naturalmente, mas não é seguro nem idempotente por garantia do método — um cliente não pode repetir automaticamente um POST após falha de conexão sem risco de duplicar efeitos.
QUERY junta os dois lados: tem corpo, como POST, mas é seguro, idempotente e cacheável, como GET. O corpo da requisição é a própria consulta — não um recurso a ser criado ou alterado.
Safe vs. idempotente
Um método é safe quando a requisição não tem a intenção de modificar o
estado do recurso no servidor (pode gerar logs/métricas internamente, mas o recurso
consultado permanece igual). GET e QUERY são safe; POST
não necessariamente.
Uma operação é idempotente quando executá-la uma ou várias vezes produz o
mesmo resultado final. DELETE /contacts/10 chamado duas vezes deixa o mesmo
estado final (contato removido). Já POST /orders chamado duas vezes pode criar
dois pedidos diferentes — por isso POST não é considerado idempotente por padrão.
| Propriedade | GET | QUERY | POST |
|---|---|---|---|
| Seguro (safe) | Sim | Sim | Não garantido |
| Idempotente | Sim | Sim | Não garantido |
| Cacheável | Sim | Sim | Possível, pouco usado |
| Corpo na request | Sem semântica definida | Esperado | Esperado |
| Uso principal | Buscar recurso | Executar consulta | Processar dados |
Demo · GET vs QUERY em /contacts
GET devolve a lista inteira, sem corpo. QUERY envia um filtro no
corpo (JSON) e recebe de volta apenas os contatos que batem com ele. Repare que a resposta
inclui o header Accept-Query: "application/json" — é assim que um cliente
descobre, a partir da própria resposta, que este endpoint aceita QUERY antes mesmo de
tentar (RFC 10008, seção 4).
Cenários de validação e erro
O servidor precisa reagir de forma previsível quando a requisição foge do esperado.
Content-Type incorreto. A RFC exige rejeitar a requisição se o
Content-Type estiver ausente ou não bater com o conteúdo enviado — deve responder
415.
JSON inválido no corpo. Content-Type correto, mas o corpo não é um
JSON válido — deve responder 400.
Método não suportado. Um DELETE em /contacts
não é implementado — deve responder 405 com um header Allow
listando os métodos aceitos.
Por que essas requisições são simuladas?
O RFC 10008 é de junho de 2026. Na prática, a infraestrutura de rede ainda não acompanhou:
CDNs como o CloudFront e servidores HTTP sem suporte (como o Function URL da AWS Lambda)
ainda não reconhecem o método QUERY de forma confiável. Por isso esta página
roda inteiramente em JavaScript no navegador — a mesma lógica de filtro e validação que um
servidor real executaria, sem depender de nenhum backend.
Referência
RFC 10008 — The HTTP QUERY Method: rfc-editor.org/rfc/rfc10008.html