O que é o HTTP QUERY Method
Há anos os desenvolvedores backend enfrentam um dilema clássico: como fazer uma busca complexa via HTTP? O GET é o método certo semanticamente, mas não tem corpo de requisição. O POST aceita corpo, mas tem semântica de "criar algo", não é idempotente é não é cacheável por padrão.
A solução improvisada mais comum é colocar parâmetros complexos na query string do GET, o que fica feio, tem limite de tamanho em torno de 2000 a 8000 caracteres dependendo do servidor, é não suporta estruturas aninhadas com facilidade. Outra gambiarra é usar POST para buscas é torcer para que os caches entendam.
O RFC 10008, publicado em 2026 pelo IETF, oficializa o método QUERY como a solução definitiva para este problema. É um método HTTP de primeira classe, com semântica bem definida, suporte a corpo de requisição é comportamento cacheável por design.
Como funciona o método QUERY
O QUERY se comporta de forma semelhante ao GET em termos de semântica: ele é seguro (não modifica dados no servidor), idempotente (repetir a mesma requisição dá o mesmo resultado) é cacheável (caches podem armazenar a resposta).
A diferença central é que o QUERY aceita um corpo de requisição (request body). O conteúdo do corpo, combinado com a URL, forma a chave de cache. Isso significa que duas requisições QUERY para a mesma URL mas com corpos diferentes são tratadas como requisições distintas para fins de cache.
A chave de cache do QUERY é a combinação de URL + corpo da requisição + Content-Type. O servidor deve incluir cabeçalho Vary adequado para que proxies intermediários tratem corretamente.
Veja um exemplo de requisição usando o novo método:
QUERY /api/produtos HTTP/1.1
Host: api.exemplo.com.br
Content-Type: application/json
Accept: application/json
{
"filtros": {
"categoria": "eletronicos",
"preco_max": 2000,
"disponível": true
},
"ordenacao": "preco_asc",
"página": 1,
"por_pagina": 20
}A resposta segue o padrão HTTP normal com código 200 OK é os resultados no corpo. O servidor pode incluir Cache-Control é ETag normalmente, assim como em respostas a GET.
Principais recursos é diferenciais
O RFC 10008 define claramente o que o QUERY pode é não pode fazer. Entender esses limites é fundamental para usar o método corretamente nas suas APIs.
- Corpo de requisição sem limite prático: diferente da query string, o corpo aceita JSON, XML ou qualquer Content-Type com estruturas complexas é aninhadas.
- Semântica de leitura garantida: servidores, proxies é clientes HTTP sabem que QUERY não modifica dados, podem tomar decisões de segurança é cache baseadas nisso.
- Idempotência nativa: repetir a mesma requisição QUERY com o mesmo corpo deve retornar o mesmo resultado, permitindo retry automático com segurança.
- Cacheável por padrão: ao contrário do POST, respostas QUERY podem ser cacheadas sem configuração especial no servidor ou proxy.
- Compatível com toda a infraestrutura HTTP: load balancers, CDNs é reverse proxies que entendem HTTP/1.1 é HTTP/2 suportam o método sem modificações.
Como começar: suporte é implementação
O suporte ao método QUERY ainda está chegando nas principais bibliotecas é frameworks no momento em que este artigo foi escrito. A boa notícia é que a implementação é direta, pois a maior parte da infraestrutura HTTP já existe.
Em JavaScript com fetch, o método é especificado como qualquer outro:
// Requisicao QUERY com fetch API
const resposta = await fetch('/api/produtos', {
method: 'QUERY',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
filtros: { categoria: 'eletronicos', preco_max: 2000 },
ordenacao: 'preco_asc'
})
});
const dados = await resposta.json();
console.log(dados);No backend com Node.js é Express, o roteamento segue a mesma lógica:
// Express ainda não tem app.query() nativo
// Usar router.all() ou middleware personalizado
app.all('/api/produtos', (req, res, next) => {
if (req.method === 'QUERY') {
const filtros = req.body;
// processar busca com filtros do corpo
return buscarProdutos(filtros).then(r => res.json(r));
}
next();
});Em .NET com ASP.NET Core, é possível adicionar suporte via atributo customizado enquanto o framework não tem suporte nativo completo:
// ASP.NET Core - aceitar metodo QUERY
[HttpMethod("QUERY", "api/produtos")]
public async Task BuscarProdutos(
[FromBody] FiltrosProdutos filtros)
{
var resultado = await _service.BuscarAsync(filtros);
return Ok(resultado);
} Exemplo prático: API de busca avançada
Imagine uma API de busca de imóveis onde o usuário pode filtrar por bairro, faixa de preço, número de quartos, área mínima é máxima, é ordenar por diferentes critérios. Com GET, isso seria um pesadelo de query string. Com QUERY, fica elegante:
QUERY /api/imoveis HTTP/2
Host: api.imobiliaria.com.br
Content-Type: application/json
{
"bairros": ["Batel", "Agua Verde", "Bigorrilho"],
"faixa_preco": { "min": 300000, "max": 800000 },
"quartos": { "min": 2 },
"area_m2": { "min": 60, "max": 150 },
"caracteristicas": ["garagem", "piscina"],
"ordenar_por": "preco_asc",
"página": 1
}Se o mesmo usuário fizer a mesma busca duas vezes, o cache HTTP pode retornar o resultado armazenado sem bater no banco de dados. Com POST isso não funcionária automaticamente.
A resposta inclui os imóveis encontrados é metadados de paginação, é o servidor pode definir Cache-Control: max-age=60 para cachear resultados por 1 minuto, algo impossível de garantir com POST.
Comparação com alternativas
Antes do RFC 10008, os desenvolvedores tinham três opções, todas com compromissos ruins:
GET com query string longa que quebra em alguns servidores. POST com semântica errada que não é cacheável. GraphQL ou OData para resolver algo que deveria ser nativo no HTTP.
Um método com a semântica certa, corpo livre, idempotente é cacheável. Sem depender de camadas extras como GraphQL quando você só precisa de busca flexível.
Em relação ao GraphQL: o QUERY não é substituto do GraphQL. Se você precisa de seleção granular de campos, múltiplas queries em lote é schema tipado, GraphQL ainda é a escolha. O QUERY HTTP é mais baixo nível é complementar.
Em relação ao OData: o OData usa GET com query string para filtros avançados é tem seu nicho em APIs corporativas. O QUERY é mais simples é não impõe um dialeto de query específico.
Em relação ao POST para buscas: é a gambiarra mais comum. Funciona, mas não é semânticamente correto é os caches não sabem que podem armazenar a resposta.
Pontos positivos é limitações
O QUERY resolve um problema real é bem definido. Mas é importante entender o que ele não é.
- Positivo: semântica HTTP correta para buscas complexas.
- Positivo: cacheável nativamente, reduzindo carga no servidor.
- Positivo: idempotente, permite retry seguro em falhas de rede.
- Positivo: elimina o limite de tamanho da query string.
- Limitação: suporte ainda chegando em frameworks é ferramentas (junho 2026).
- Limitação: caches intermediários mais antigos podem não reconhecer o método.
- Limitação: não resolve seleção granular de campos como GraphQL.
Proxies HTTP que não reconhecem o método QUERY podem bloqueá-lo ou tratá-lo como inválido. Verifique a compatibilidade do seu stack de infraestrutura antes de adotar em produção.
Casos de uso reais
O QUERY brilha em cenários específicos onde buscas complexas são parte central do produto.
- É-commerce: busca de produtos com múltiplos filtros (categoria, marca, faixa de preço, avaliação, disponibilidade, frete grátis). Sem QUERY, a query string fica enorme ou você precisa de POST.
- Portais imobiliários é de vagas: busca com filtros geográficos, faixas de valores é características múltiplas. Dados estruturados encaixam perfeitamente no corpo JSON.
- APIs de analytics: consultas de métricas com filtros de data, dimensões, métricas agrupadas. Hoje feitas com POST, mas sem cache automático.
- Sistemas de BI é relatórios: queries parametrizadas que precisam ser cacheadas por minutos ou horas para aliviar o banco de dados.
Dicas é boas práticas
Se você vai implementar QUERY em uma API nova ou migrar uma existente, algumas práticas vão te poupar de dores de cabeça.
Inclua um campo version ou v no corpo do QUERY desde o início. Isso facilita a evolução do schema de filtros sem quebrar clientes antigos.
- Sempre retorne
Content-Type: application/jsonnas respostas para facilitar a integração. - Inclua
Cache-Controlexplícito nas respostas. O padrão cacheável não significa que o cache vai durar para sempre. - Documente o schema do corpo com JSON Schema ou OpenAPI 3.1 (que tem suporte ao método QUERY).
- Para compatibilidade com clientes que não suportam QUERY ainda, considere manter um endpoint
POST /api/recurso/buscaem paralelo.
Nunca confie no conteúdo do corpo de uma requisição QUERY sem validação. Assim como em POST, o body pode conter dados maliciosos ou mal formatados. Use schema validation no servidor.
Vale a pena adotar o HTTP QUERY Method?
Se você está construindo uma API nova que terá buscas com múltiplos filtros, sim, vale estruturar pensando no QUERY. Mesmo que o suporte nativo dos frameworks ainda esteja chegando, implementar no nível do router é simples é você já garante a semântica correta desde o início.
Se você tem uma API existente usando POST para buscas, a migração faz sentido quando o cache for importante para você. Se os resultados das buscas puderem ser cacheados é isso reduzir carga no banco, o ganho justifica a mudança.
Para equipes que já usam GraphQL, o QUERY HTTP não substitui. São ferramentas com níveis de abstração diferentes. Use GraphQL quando precisar de flexibilidade no cliente para escolher campos, use QUERY quando quiser a simplicidade do REST com filtros complexos no corpo.
O próximo passo é acompanhar o suporte nos frameworks que você usa (Express, FastAPI, ASP.NET, Laravel) é ficar de olho no suporte nos clientes HTTP como Axios, HTTPx é Fetch API. A especificação já está definida, o ecossistema está convergindo.
Comentários
Deixar um comentárioVocê precisa ter uma conta no CuritibaBlog para comentar.