Understanding the HTTP QUERY Method: Safety, Idempotence, and Use Cases
This article explains the HTTP QUERY method—a safe, idempotent request type that carries query payloads in the body, contrasts it with GET and POST, details caching behavior, the Accept-Query header, and provides practical examples of direct and indirect responses.
Last week the author discovered an issue on GitHub discussing the HTTP QUERY method, a safe and idempotent request type that can include a request payload.
1. Introduction
The HTTP QUERY request method is safe and idempotent, allowing the request content to be sent in the body. When a GET request’s query string becomes too large to fit in the URI, a QUERY request can be used. For example:
<code>GET /feed?q=foo&limit=10&sort=-published HTTP/1.1
Host: example.org
</code>If the query parameters grow to several kilobytes, many implementations limit the size, so POST is often used as a substitute:
Typical POST request example
<code>POST /feed HTTP/1.1
Host: example.org
Content-Type: application/x-www-form-urlencoded
q=foo&limit=10&sort=-published
</code>However, this change shares the same fundamental limitation as GET: without specific knowledge, it is not obvious that a safe, idempotent query is being performed.
The QUERY method offers a middle ground between GET and POST. Like POST, the query input is sent in the request payload, but unlike POST, the method is explicitly safe and idempotent, enabling caching and automatic retries.
2. QUERY Method
The QUERY method initiates a server‑side query. Unlike GET, which returns a representation of the resource identified by the URI, QUERY requests the server to execute a query over a dataset described by the request payload. The response payload is not assumed to be a representation of the URI‑identified resource.
The request payload defines the query, and any content type with appropriate query semantics may be used.
QUERY requests are safe and idempotent with respect to the resource identified by the request URI; they do not change the target resource’s state, though the server may allocate compute and memory resources.
Successful responses may indicate the result in various ways, such as a 204 No Content when no results are found, or a 200 with a payload describing the outcome. Servers may also respond with a 3xx redirect containing a Location header, allowing the client to retrieve results via a subsequent GET request.
If conditional headers like If-Modified-Since, If-Unmodified-Since, If-Match, If-None-Match, or If-Range are present, the QUERY becomes a “conditional QUERY,” executed only when those conditions on the target resource are met.
2.1 Caching
Responses to QUERY requests can be cached; caches use the request content as part of the cache key. The cache key should be normalized to remove semantically irrelevant differences, improving cache efficiency:
Remove content encoding
Normalize media type suffixes (e.g., "+json") based on format conventions
Normalize the semantic content indicated by the Content‑Type
Normalization is only for generating the cache key and does not alter the request itself.
2.2 "Accept-Query" Header
Servers may use the "Accept-Query" response header to signal support for the QUERY method and indicate which query format media types are acceptable.
<code>Accept-Query = 1#media-type
</code>The header lists media types defined in RFC 7231 §8.3.1, and the order of types is insignificant.
3. Examples
The following non‑normative examples use a simple, hypothetical plain‑text SQL‑like query syntax and return results as CSV. Implementations may use any format.
3.1 Simple Direct QUERY Response
<code>QUERY /contacts HTTP/1.1
Host: example.org
Content-Type: example/query
Accept: text/csv
select surname, givenname, email limit 10
</code>Response:
<code>HTTP/1.1 200 OK
Content-Type: text/csv
surname, givenname, email
Smith, John, [email protected]
Jones, Sally, [email protected]
Dubois, Camille, [email protected]
</code>3.2 Simple Indirect QUERY Response (303 See Other)
<code>QUERY /contacts HTTP/1.1
Host: example.org
Content-Type: example/query
Accept: text/csv
select surname, givenname, email limit 10
</code>Response:
<code>HTTP/1.1 303 See Other
Location: http://example.org/contacts/query123
</code>Retrieve the query result:
<code>GET /contacts/query123 HTTP/1.1
Host: example.org
</code>Response:
<code>HTTP/1.1 200 OK
Content-Type: text/csv
surname, givenname, email
Smith, John, [email protected]
Jones, Sally, [email protected]
Dubois, Camille, [email protected]
</code>4. Conclusion
The HTTP QUERY method is a promising proposal that could simplify server‑side data request APIs by removing the need to choose between GET and POST. While the SQL‑like query examples are illustrative, broader adoption by server and client implementations would be valuable.
Java Architecture Diary
Committed to sharing original, high‑quality technical articles; no fluff or promotional content.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.