Back to Latest PostsBlog

Meet QUERY: The New HTTP Method That Fixes a Decade-Old Problem

By Carlos Diaz · July 21, 2026 · 4 min read

If you've built APIs, you know the drill: GET for reading data, POST for creating it, PUT/DELETE for updating and removing it. Those four verbs have been the backbone of HTTP for decades. Now there's a fifth one on the way, called QUERY, and it solves a problem that developers have been working around for years.

The Problem: GET and POST Don't Quite Fit

Say you're building a product search API. You want to filter by category, price range, rating, and sort order. Two options exist today, and both have downsides.

Option 1: Use GET. Simple, and the browser caches it automatically. But everything has to go in the URL:

PLAINTEXT
GET /api/products/search?category=electronics&minPrice=100&maxPrice=500&rating=4&sortBy=rating

This gets messy fast. URLs have length limits. Every value arrives as a string, so a boolean like true or a number like 4 needs manual conversion on the server. Nested filters (like "electronics OR books, but not toys") are painful to encode. And the whole URL, filters included, ends up in your server logs.

Option 2: Use POST. You can send a clean JSON body instead:

JSON
{
  "categories": ["electronics"],
  "price": { "min": 100, "max": 500 },
  "minRating": 4,
  "sortBy": "rating"
}

No encoding headaches. But POST means "I'm creating or changing something" to every browser and CDN in existence. Even though your search doesn't modify anything, the browser will never cache the response, and you can't bookmark the request. This is exactly why GraphQL — a language built entirely around queries — sends every request over POST. It needs a body for the query, but it pays for that with zero caching.

The Solution: QUERY

QUERY is a new HTTP method built to be the best of both:

  • Like GET, it's safe and idempotent — it never modifies anything on the server, and calling it repeatedly gives you the same result. That's what makes it cacheable.
  • Like POST, it lets you send a request body — so you get clean, structured JSON without cramming everything into a URL.

Here's the same search, this time with QUERY:

JAVASCRIPT
const response = await fetch('/api/products/search', {
  method: 'QUERY',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    categories: ['electronics'],
    price: { min: 100, max: 500 },
    minRating: 4,
    sortBy: 'rating',
  }),
});
 
const data = await response.json();
console.log(data);

How It Looks on the Server

Node.js and Express (version 5+) already support QUERY. Here's a minimal example showing all three methods side by side:

JAVASCRIPT
import express from 'express';
const app = express();
app.use(express.json());
 
// The old way: everything in the URL
app.get('/api/products/search', (req, res) => {
  const { category, minPrice, maxPrice, rating, sortBy } = req.query;
  res.json(searchProducts({ category, minPrice, maxPrice, rating, sortBy }));
});
 
// The workaround: a body, but never cached
app.post('/api/products/search', (req, res) => {
  res.json(searchProducts(req.body));
});
 
// The new way: a body AND cacheable
app.query('/api/products/search', (req, res) => {
  res.json(searchProducts(req.body));
});
 
app.listen(3000);

Why Not Just Add a Body to GET?

Good question — and the answer is basically "because it would break the internet." Nothing in the HTTP spec explicitly forbids sending a body with GET, but the spec says you shouldn't, and every browser, proxy, and server has built its own behavior around that assumption. Some tools ignore a GET body, some reject it, some pass it along. Suddenly changing that behavior everywhere would be chaotic. Introducing a brand-new method with clearly defined rules is far safer.

When to Use Which

flowchart TD
    A[Fetching data from an API] --> B{Do you need to send complex,<br/>nested, or non-string data?}
    B -- No --> C[Use GET]
    B -- Yes --> D{Should the response<br/>be cacheable or bookmarkable?}
    D -- Yes --> E[Use QUERY]
    D -- No, and it changes data --> F[Use POST]

What This Means Right Now

QUERY is still on its way to becoming a full web standard, and browsers haven't implemented native caching for it yet — that will come later, the same way it eventually did for GET. Support already exists in Node.js and Express, and more frameworks are expected to follow as the standard matures.

If you want to try it in production today, do it carefully: keep your existing GET or POST endpoint working as-is, and add QUERY as an extra, optional endpoint. That way clients that understand QUERY can use it, and everyone else keeps working exactly as before.

Wrap-Up

QUERY fills a real gap in HTTP: a way to run safe, cacheable, idempotent reads while still sending a full request body. It won't replace GET or POST — it sits between them, purpose-built for complex read queries. Keep an eye on framework and browser support over the next couple of years; this is one of those rare additions to a core internet protocol worth understanding early.