writing/blog/2026/07
BlogJul 5, 2026·6 min read

HTTP QUERY Method: RFC 10008 Developer Guide (2026)

RFC 10008 introduces HTTP QUERY, the first new method in 16 years: a safe, idempotent, cacheable request with a body. Learn how it works and when to adopt it.

On June 15, 2026, the IETF published RFC 10008, defining the HTTP QUERY method — the first new HTTP method since PATCH in 2010. Sixteen years is a long time in web development, and QUERY did not appear on a whim: the idea dates back to a 2015 draft, was revived at the 2019 HTTP Workshop, adopted by the httpbis working group in 2021 (originally under the name SEARCH), and finally reached Standards Track publication this summer.

QUERY solves a problem every backend developer has worked around for years: there was no HTTP method for a read-only request that carries a body. In this guide we cover what QUERY is, why it matters, how caching works, what framework support looks like today, and when you should actually adopt it.

The problem: GET vs. POST for complex queries

Consider a typical product search. The "correct" RESTful approach is GET with query parameters:

GET /products?category=shoes&maxPrice=100&sort=price_asc HTTP/1.1
Host: shop.example

This works until your filters grow. Faceted search, nested conditions, geo queries, or anything resembling a real query language quickly produces URLs that are painful to build, hit practical length limits in proxies and servers, and leak query details into access logs and browser history.

So developers reach for POST:

POST /api/search HTTP/1.1
Content-Type: application/json
 
{ "category": "shoes", "maxPrice": 100, "sort": "price_asc" }

It works, but the semantics are wrong. POST tells every intermediary — caches, proxies, retry logic, monitoring tools — that this request may change state. That means:

  • No caching. Responses to POST are not reusable by shared caches in practice.
  • No safe retries. A client that loses the connection cannot blindly resend a POST; it might duplicate a side effect. Your search endpoint has no side effects, but nothing in the protocol says so.
  • Opaque intent. POST /search, POST /reports/run, and POST /orders all look identical at the protocol level, even though only one of them creates anything.

Every GraphQL endpoint, every Elasticsearch _search call, every reporting API has lived with this mismatch for a decade.

What QUERY brings

RFC 10008 defines QUERY as a method that "requests that the request target process the enclosed content in a safe and idempotent manner and then respond with the result of that processing." Three properties make it different from everything we had:

PropertyGETPOSTQUERY
Safe (no state change)YesNoYes
Idempotent (retryable)YesNoYes
Request bodyDiscouragedYesYes
Cacheable responseYesRarelyYes

A QUERY request looks like a POST but behaves like a GET. Here is the canonical example from the RFC:

QUERY /contacts HTTP/1.1
Host: example.org
Content-Type: application/x-www-form-urlencoded
Accept: application/json
 
select=surname,givenname,email&limit=10&match=%22email=*@example.*%22
HTTP/1.1 200 OK
Content-Type: application/json
 
[
  { "surname": "Smith", "givenname": "John", "email": "smith@example.org" },
  { "surname": "Jones", "givenname": "Sally", "email": "sally.jones@example.com" }
]

The body can be any media type — form-encoded, JSON, GraphQL, SQL-like DSLs. The server advertises what it accepts through the new Accept-Query response header, which lists supported media ranges using Structured Fields syntax.

Because QUERY is idempotent, clients and libraries may automatically retry a failed request after a connection drop — something they must never do with POST. Because it is safe, monitoring and security tooling can treat it as read-only traffic.

Caching: the interesting part

GET responses are cached by URL. QUERY responses can be cached too, but the cache key must incorporate the request content, not just the URI. Two QUERY requests to /search with different JSON bodies are different cache entries.

The RFC goes further and allows caches to normalize request content before computing the key — collapsing differences in content encoding, JSON whitespace and key ordering conventions, or media subtype suffixes. Done well, this means {"a":1,"b":2} and a reordered, pretty-printed equivalent can hit the same cache entry. Done carelessly, normalization bugs can serve the wrong response to the wrong query, which the spec explicitly flags as a security consideration.

One more elegant detail: a server can answer QUERY with 303 See Other, pointing the client at a URI that represents the query result. The client then issues a plain GET — turning an expensive body-carrying query into a shareable, conventionally cacheable resource.

Framework and ecosystem support in 2026

Adoption is early but real:

  • .NET 10 ships first-class support on both sides. The client exposes HttpMethod.Query, and ASP.NET Core 10 provides HttpMethods.Query plus HttpMethods.IsQuery():
// Client
using var request = new HttpRequestMessage(HttpMethod.Query, "https://api.example/products/search")
{
    Content = JsonContent.Create(filter)
};
 
// Server (ASP.NET Core 10)
app.MapMethods("/products/search", new[] { HttpMethods.Query }, async (HttpRequest req) =>
{
    var filter = await req.ReadFromJsonAsync<ProductFilter>();
    return Results.Ok(await search.RunAsync(filter));
});

Convenience helpers like MapQuery() and an [HttpQuery] attribute were cut from the release, so teams write small wrapper extensions for now.

  • Node.js and others: since QUERY is syntactically just another method token, most HTTP servers pass it through; router-level support is landing gradually across frameworks.
  • Browsers: fetch and XHR cannot send QUERY yet, and QUERY is not a CORS-safelisted method, so cross-origin use always triggers a preflight. For now, QUERY shines in server-to-server communication.
  • CDNs and proxies: despite RFC authorship involving Cloudflare and Akamai engineers, large-scale QUERY response caching at the edge is not reliable yet.
  • OpenAPI: version 3.1 has no way to describe QUERY endpoints; ASP.NET Core simply excludes them from generated documents.

Should you adopt QUERY now?

A pragmatic checklist:

Adopt now if you control both client and server — internal microservices, backend-for-frontend layers, data APIs behind your own gateway. You get honest semantics, safe automatic retries, and forward-compatible caching for free.

Wait if your consumers are browsers, third-party integrators on OpenAPI-generated SDKs, or if you depend on edge caching of query results today.

Design tip: expose QUERY alongside a POST fallback on the same route during the transition, and advertise support with Accept-Query. Clients that understand QUERY get the better semantics; older ones lose nothing.

At Noqta, we see QUERY as a natural fit for the search and reporting endpoints in the API-first architectures we build — especially in AI agent pipelines, where agents calling tools over HTTP benefit enormously from requests that are declared safe and retryable at the protocol level.

Conclusion

QUERY closes a gap that has existed since HTTP/1.1: read-oriented requests with real payloads no longer need to masquerade as writes. The method is standardized, .NET 10 already ships it, and the rest of the ecosystem is following. You do not need to rewrite your APIs tomorrow — but the next time you design a search endpoint and feel the familiar discomfort of POST /search, know that the protocol finally has a better answer.

Sixteen years between new methods suggests this one was worth the wait.