The HTTP method web devs have wanted for a decade: a GET that can carry a body
RFC 10008 standardizes HTTP QUERY: a request that's safe and idempotent like GET but ships a body like POST. Here's what it fixes and who supports it.
The IETF just shipped a method web developers have wanted for years. On June 18, the RFC Editor published RFC 10008, standardizing a new HTTP method called QUERY: a request that reads data without changing anything, like GET, but ships a real request body, like POST. Ever fought a giant filter crammed into a query string? This is the fix.
It sounds small. A new verb. But search, filtering, and GraphQL-style APIs have been wedged between two bad options for over a decade, and QUERY is the first standards-track answer that doesn’t ask you to pick the lesser evil. The spec landed on the Hacker News front page within hours, which tells you the pain is widely felt.
The GET-with-a-body trap
Here’s the problem in one sentence. You want to read data, the input is complicated, and HTTP gives you no good way to do both. That gap has shaped how nearly every search box, filter panel, and reporting API on the web is built, and the workarounds for it have quietly cost real money in cache misses and origin load.
GET is the right semantic choice for a read. It’s a safe method, it’s idempotent, and its responses cache beautifully. But GET’s input lives in the URL. Once your search filters, sort orders, and pagination cursors grow past a few hundred bytes, you’re fighting URL length limits. Browsers, proxies, and servers all cap URLs at different points, often around 2,000 to 8,000 characters, and there’s no portable maximum. Add a 50-field faceted filter and you blow past it.
Can’t you just put a body on a GET? Technically the wire format allows it. In practice, the HTTP spec says the body on a GET has no defined meaning, so servers and intermediaries are free to ignore it, strip it, or choke on it. The Fetch standard that browsers implement flatly forbids it. So “GET with a body” is the kind of thing that works on your laptop and fails behind a load balancer.
That leaves POST. And POST works, which is why everyone uses it for search. But POST is the wrong tool. It tells every cache, proxy, and CDN in the path “this might change something, don’t reuse the answer.” You lose response caching, you lose safe automatic retries, and you’ve lied about what your endpoint does. A search that says POST is a search that can’t be cached at the edge.
What QUERY actually is
QUERY collapses the trade-off. In the words of the spec, a QUERY request asks “the target resource to perform a query operation” where “the content of the request and its media type define the query.”
The two properties that matter are stated plainly in RFC 10008. First, safety: “QUERY requests are safe with regard to the target resource,” meaning “the client does not request or expect any change to the state of the target resource.” Second, idempotency: “QUERY requests are idempotent; they can be retried or repeated when needed, for instance, after a connection failure.”
So you get GET’s contract, the body of a POST, and a method name that finally matches what your search endpoint has been doing all along. The request body holds the query in whatever format you like, JSON, GraphQL, SQL-ish DSL, as long as you set the Content-Type. The spec is strict here: servers “MUST fail the request if the Content-Type request field is missing or is inconsistent with the request content.” No guessing.
A QUERY to a product search might look like this:
QUERY /products HTTP/1.1
Host: shop.example
Content-Type: application/json
Accept: application/json
{
"filter": { "category": "laptops", "price": { "lte": 1500 } },
"sort": [{ "field": "rating", "order": "desc" }],
"limit": 25
}
No URL gymnastics. No pretending a read is a write. The same payload that would’ve been a POST is now honestly a read, and any cache or proxy in the path can treat it that way. The server reads the body, runs the query against the target resource, and returns results, all under a contract that promises nothing on the server changed.
Caching is the whole point
The feature that makes QUERY worth a new method is caching, and the spec handles the hard part. A POST search can’t be cached because caches key on the URL, and the URL doesn’t carry the query. QUERY moves the query into the body, so the cache has to key on the body too.
RFC 10008 says exactly that: “The response to a QUERY method is cacheable; a cache MAY use it to satisfy subsequent QUERY requests,” and critically, “the cache key for a QUERY request MUST incorporate the request content.” That last line is the unlock. Two different filter payloads sent to /products produce two different cache entries, the way two different query strings would under GET. A shared CDN cache can finally serve repeat searches without round-tripping to your origin.
There’s a second trick for clients that want a plain cacheable URL afterward. A server can answer a QUERY with a Content-Location header pointing at a URL that represents the result, so a follow-up GET can fetch or re-run the query without resending the body. You query once with the heavy payload, then cache and share a clean link.
Who actually supports it
This is where honesty matters, because a fresh RFC is not the same as something you can ship Monday. Right now, support is thin and the spec itself ships with no implementation list.
The authorship is the strongest signal. RFC 10008 was written by Julian Reschke of greenbytes, James Snell of Cloudflare, and Mike Bishop of Akamai. Two of the three work at major CDNs, and CDNs are exactly the layer that benefits most from a cacheable safe-with-a-body method. Edge support landing ahead of framework support is a real possibility.
On the framework side, it’s early. Spring evaluated adding QUERY in issue #32975 and closed it as not planned, marking it superseded while the spec stabilized. Browsers don’t expose QUERY from fetch() yet, since the Fetch standard still bans bodies on safe methods and would need its own update. The working draft, draft-ietf-httpbis-safe-method-w-body, traces back through more than a dozen revisions to discussions at the 2019 HTTP Workshop, so the idea is old even if the RFC is new.
The cleanest near-term win is GraphQL. As The API Changelog notes, GraphQL already pushes queries through POST and loses HTTP caching because of it. Switching its query operations to QUERY restores edge caching without touching the query language itself, which is a rare migration that costs almost nothing and buys back a whole performance layer. Don’t expect your stack to support it overnight, though. Real adoption needs client libraries, server frameworks, and CDN engines to all move, and each of those moves on its own schedule.
Why you’re hearing about this now
The timing is simple: a draft that bounced around the HTTP Working Group for years finally became a numbered, standards-track RFC, and that’s the moment infrastructure vendors start writing code against it. A Proposed Standard is the green light implementers wait for.
For most teams, the move today is to watch, not rewrite. If you run search or filter endpoints behind Cloudflare or Akamai, keep an eye on their changelogs, because edge-level QUERY caching is the first place this pays off. If you maintain an HTTP client or a framework, the spec is stable enough to prototype against now. And if you’ve been apologizing for a POST-based search API in design reviews, you finally have a standard to point at. The verb you wanted exists. Now the ecosystem has to catch up to it.
Share this article
Quick reference
Sources
- RFC 10008: The HTTP QUERY Method — IETF / RFC Editor
- The HTTP QUERY Method (httpbis working draft) — HTTP Working Group
- Add support for the HTTP QUERY method (spring-framework#32975) — GitHub / Spring
- The HTTP QUERY Method — The API Changelog
Frequently Asked
- Is HTTP QUERY a replacement for GET?
- No. GET stays the default for fetching a resource by URL. QUERY is for read operations whose input is too big or too structured to fit in a URL, like a complex search or a GraphQL query.
- Can I use QUERY in the browser today?
- Not from fetch() yet. The Fetch standard still forbids a body on safe methods, and no shipping browser exposes QUERY. Server-to-server clients and CDNs are where it'll appear first.
- How is QUERY different from the old SEARCH method?
- SEARCH came from WebDAV and carried WebDAV baggage. The working group started there, then chose the name QUERY to signal a clean, general-purpose safe-with-a-body method instead.
- Does a QUERY response get cached?
- Yes, but the cache key must include the request body, not just the URL. RFC 10008 spells this out so two different query bodies to the same URL don't collide in a shared cache.