HTTP QUERY: the new method that resolves the limbo between GET and POST

Equipe HcodeJune 24, 20264 min read

In this article

For more than two decades, those building APIs have faced the same dilemma whenever a search becomes too complex to fit in a URL: use GET and exceed query string size limits, or use POST and forgo the safe and cacheable semantics that GET offers. The IETF is formalizing the answer to this impasse: the QUERY method, defined in the draft draft-ietf-httpbis-safe-method-w-body, which already has experimental implementations in browsers and server frameworks.

The problem that motivated the new method

GET was designed to retrieve a resource and carries two important guarantees in the HTTP specification:

  • Safe: it should not cause side effects on the server.
  • Idempotent: repeating the same request multiple times produces the same result.

These guarantees are what allows proxies, CDNs, and browsers to cache GET responses and perform automatic retries without fear of duplicating an action. The problem is that the HTTP/1.1 specification does not reliably define a request body for GET — several servers, proxies, and libraries simply discard it. This forces those who need to send complex filters, large lists of IDs, or nested structures (the classic case of advanced searching, reporting, or GraphQL) to resort to POST.

The POST, on the other hand, is neither safe nor idempotent by definition. An HTTP client, a proxy, or the browser itself cannot assume that repeating a POST is harmless — that’s why it is never automatically cached and requires extra care in retries.

Practical result: API teams end up using POST /search or POST /graphql for operations that are, in essence, reads. It works, but standard HTTP cache, implicit idempotence, and the semantic clarity that the call does not change state is lost.

What the QUERY method proposes

QUERY is a new HTTP method that combines the best of both worlds:

  • Has a request body, like POST, allowing structured payloads to be sent (JSON, XML, whatever format makes sense).
  • Is safe and idempotent, like GET — the server commits to treating it as a read, without side effects.
  • Is cacheable under the same cache rules as HTTP, provided the response includes the appropriate headers (Cache-Control, ETag etc.), as the request body becomes part of the cache key.

In practice, a complex search call would look like this:

QUERY /products HTTP/1.1
Host: api.example.com
Content-Type: application/json
Accept: application/json

{
  "filters": {
    "category": ["electronics", "computers"],
    "minPrice": 100,
    "maxPrice": 2000
  },
  "sortBy": "relevance",
  "page": 1
}

The server responds as it would to a GET: it can attach cache headers, can be served by a reverse proxy, and the client knows it can repeat the call without fear of duplicating anything.

Why this matters in practice

Advanced searches and filters. This is the most direct use case: search endpoints with multiple filters, large ID lists, or extensive free text no longer need to choose between gigantic URLs (GET with query string of hundreds of characters) or forgoing caching (POST).

GraphQL-like APIs and reporting. Queries that currently only work via POST — because the query body doesn’t fit or isn’t safe in a URL — will have a dedicated method that accurately expresses the intent “this is a read.”

Native HTTP caching. With QUERY, CDNs and proxies can, in theory, cache responses from complex searches without requiring the application to implement its own caching layer for this — provided the infrastructure supports the method.

Clarity of intent. Logs, observability tools, and authorization middlewares can now distinguish “this is a read operation with payload” from “this is a write,” which simplifies auditing rules and creates differentiated rate limit policies for reads vs. writes.

What changes for those building APIs

Adopting QUERY today requires attention to several points:

  • Infrastructure support is still partial. Browsers, proxies, load balancers, and HTTP frameworks need to explicitly recognize the method. Where support is lacking, calls should fall back to POST with a header or convention signaling the reading semantics (some frameworks already adopt this as a fallback).
  • It remains “regular” HTTP. QUERY does not replace GET or POST — it is a third method for the specific case of reading with structured payload. Write operations remain in POST, PUT, PATCH, and DELETE.
  • Caching requires discipline with headers. As the cache key now depends on the request body (and not just the URL), it is necessary to ensure that Cache-Control, Vary, and ETag are correct to avoid cross responses between different payloads.
  • It is still a draft in evolution. As it is in the process of being standardized at the IETF, details of behavior (content negotiation, interaction with Content-Length, behavior on redirection) may change until the final publication as RFC.

Where to follow the adoption

Being a new method, the recommendation for engineering teams is to treat QUERY as an evolution to observe before depending on it in production: validate the support of the server runtime, the reverse proxy, and the HTTP clients used (browsers, SDKs, internal tools) before migrating critical endpoints. For complex searches and reports that currently struggle with giant URLs or POST without caching, it is advisable to already design the API keeping in mind a future migration to QUERY — maintaining the search payload well-defined and the operation free of side effects, exactly as the new method requires.

Keep learning with Hcode

Sign up for the course platform and follow the next blog guides.