Introduction
QUERY is an HTTP request method for performing server-side search and read operations in which the parameters of the request are transmitted in the request body rather than the request URI. It combines the semantic guarantees of GET — the request is safe and idempotent — with the ability to carry a request body, which was previously available only through POST.
This article describes the purpose of the method, the limitations of prior approaches, the structure of a QUERY request etc.
Every time your app talks to a server, it uses a method— a single word that signals your intention:
GET means “just give me data, I’m not changing anything.”
POST means “here’s some data, do something with it” — like creating an account or placing an order.
These signals aren’t just for the server. Every system sitting between you and that server — caches, proxies, load balancers — reads the method to decide how to behave. That detail matters a lot in a moment.
Problem statement
Read operations that accept complex input — filtering, sorting, pagination, and nested conditions — have been implemented using one of two methods, each method has its own limitations.
GET with parameters in the URI
GET is the semantically correct method for a read operation. However, GET requires that all request parameters be encoded in the request URI. This introduces the following limitations:
URI length limits vary across clients, proxies, and servers, and are not reliably known in advance.
Structured or nested data is difficult to encode in a URI-safe form and produces unreadable request strings.
Request URIs are frequently logged and stored, which is undesirable when the request carries sensitive parameters.
POST
POST removes the encoding and size constraints by carrying parameters in the request body. However, POST is defined as neither safe nor idempotent. As a result, intermediaries cannot determine from the method alone that the operation is a read. The consequences are:
Press enter or click to view image in full size
![]()
The QUERY method
QUERY resolves this problem. It permits request parameters to be carried in the request body, while declaring the request to be safe and idempotent. Intermediaries may therefore treat a QUERY request as a read. its response is cacheable, and the request may be retried on failure.
Press enter or click to view image in full size
![Problem Resolution]()
Request format
A QUERY request carries the search definition in the request body. The content-type header is mandatory and identifies the format of that body.
QUERY /products HTTP/1.1
Host: shop.example.com
Content-Type: application/json
{
"price": { "lt": 30 },
"category": "shoes",
"color": ["red", "blue"],
"sort": "-rating",
"page": 2
}
The body format is determined by the resource and indicated by content-type; permissible formats are JSON, SQL, GraphQL, or an application-defined filter syntax. A server that cannot process the supplied format should respond accordingly (for example, with a status indicating an unsupported media type).
Summary
QUERY provides a method for read operations that carries request parameters in the body while retaining the safe and idempotent semantics of GET. It addresses the encoding and size limitations of GET and the loss of caching and retry semantics incurred when POST is used for reads.
Thank You, and Stay Tuned for More!