DEV Community

Ganesh Joshi
Ganesh Joshi

Posted on

HTTP QUERY Method: What It Is and Why It Matters

This post was created with AI assistance and reviewed for accuracy before publishing.

If you have been building REST APIs for any length of time, you have hit the same awkward wall. You need to send a complex search query to the server, but GET requests cannot carry a body. So you either cram everything into query string parameters until the URL looks like a ransom note, or you misuse POST and pretend a read-only operation is a write. Neither feels right, because neither is right.

That frustration is exactly why the IETF is finalizing a new HTTP method: QUERY.

What the QUERY Method Actually Does

QUERY is a safe, idempotent HTTP method designed to carry a request body for read-only retrieval operations. Think of it as GET with a body attached by design rather than by workaround.

The draft spec (draft-ietf-httpbis-safe-method-w-body) defines it clearly: a QUERY request retrieves a representation of a resource based on the content of the request body. The server is not expected to mutate state. The client is not expected to retry POST if the connection drops. Both sides understand the contract.

This matters because the safe and idempotent semantics are machine-readable promises. Caches can act on them. Load balancers can route around them. Middleware can log them differently. When you bend POST into a search endpoint, you lose all of that signaling.

Why GET + Query Strings Breaks Down

Most developers discover the 2,048-character URL limit the hard way. You build a filter UI with 15 checkboxes, a date range picker, and a fulltext field. Users start combining options and suddenly some requests just fail. No error. The URL gets silently truncated in older proxies, or the server returns a 414.

The other footgun is encoding. Complex JSON filters inside a query string need to be percent-encoded, then decoded, then parsed. Every layer that touches the URL has a chance to mangle special characters. You end up writing defensive decode-and-retry logic that should not have to exist.

GraphQL took the most opinionated escape route: wrap everything in POST with a JSON body. It works. But it means you opt out of HTTP-level caching entirely unless you layer Persisted Queries or a caching proxy on top.

QUERY solves this at the protocol level instead of the application level.

A Real Request Looks Like This

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

{
  "filters": {
    "category": "electronics",
    "price": { "min": 50, "max": 500 },
    "inStock": true
  },
  "sort": { "field": "price", "order": "asc" },
  "page": 1,
  "pageSize": 25
}
Enter fullscreen mode Exit fullscreen mode

Compare that to the POST workaround. Functionally identical, but a POST tells every proxy, browser, and cache in the chain "this might write something." A QUERY says "this is a read, treat it accordingly."

On the server side with Node.js it is just another method to handle:

app.query('/products', async (req, res) => {
  const { filters, sort, page, pageSize } = req.body;
  const results = await db.products.search({ filters, sort, page, pageSize });
  res.json(results);
});
Enter fullscreen mode Exit fullscreen mode

Express and most frameworks will need a router update to recognize the method name. Fetch on the client side already supports arbitrary method strings today:

const response = await fetch('/products', {
  method: 'QUERY',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(filters),
});
Enter fullscreen mode Exit fullscreen mode

So you can start experimenting right now, even before widespread server-side router support lands.

How It Compares to GET and POST

The table below cuts through the noise:

Concern GET POST QUERY
Request body allowed Technically, but ignored Yes Yes
Safe (no side effects) Yes No Yes
Idempotent Yes No Yes
Cacheable by default Yes No Yes
Good for complex filters No (URL limits) Workaround Yes

The cache story is where QUERY earns its keep. Because it is safe and idempotent, HTTP caches can store the response using the request body as part of the cache key. CDNs and reverse proxies can do the same once they implement the spec. You get the filtering power of a POST body with the caching behavior of GET.

Where the Spec Stands Right Now

As of mid-2026 the draft is in late IETF review. It is not yet an RFC. That means you should not build production infrastructure that depends on universal QUERY support in every proxy and CDN in your stack. The method is not a standard yet.

What you can do is design your API surface with QUERY in mind so the migration is clean when support firms up. Route your complex search endpoints through a consistent pattern, document that the intent is safe-and-idempotent, and keep the request body structure tidy enough to eventually benefit from cache keying.

Watch the IETF tracker. When this lands as an RFC, every major framework will ship support within a release cycle. Being aware of it now means you are not scrambling to understand it later.

What This Means for API Design

The arrival of QUERY is a quiet but meaningful correction to how HTTP maps to real-world operations. We have been living with the GET/POST mismatch for read-heavy APIs because there was no better option. Now there is one taking shape.

For new API designs I recommend sketching your read-with-filter endpoints with QUERY semantics even today. Use POST as a compatibility shim with a note in the comments. When framework support is stable, you swap the method and keep the body structure identical. The migration becomes a one-liner.

The HTTP spec does not evolve often. When it does, it usually reflects years of accumulated pain from real systems. QUERY is one of those moments. Pay attention.

Top comments (0)