All writing
· 7 min read

RIP POST /search — Meet HTTP's New QUERY Method

We've been using POST for read-only searches for decades because GET couldn't carry a body. HTTP finally has a method that says what we actually mean.

httpapi-designbackendweb

For decades, web developers have been lying to their servers.

We all do it. We use GET for fetching data until our search filters get too long or complex, and then we panic-switch to POST. We end up hitting endpoints like POST /api/products/search — using a method that does not clearly say "this is read-only," even though we are not creating, updating, or triggering anything. We are simply asking a question.

It is one of the web's favorite architectural workarounds, born out of necessity. But now the web finally has a cleaner alternative. Meet QUERY, a new HTTP method designed for complex read-only requests with a body.


1. The Problem Starts With a Search Filter

Imagine you are shopping online.

You open a shoe store app and apply filters:

  • Brand: Nike
  • Color: red
  • Size: 10
  • Price: under $50
  • Shipping: free
  • Delivery: tomorrow

To you, this is just a normal product search.

But behind the scenes, the frontend has to send all those filters to the backend. The backend then checks the database and returns matching products.

For a simple search, GET works fine:

GET /api/products?brand=nike&color=red&size=10

This is clean, readable, and cache-friendly.

But modern apps do not always send simple filters. Sometimes they need to send hundreds of IDs, nested filters, date ranges, permission scopes, sorting rules, and advanced search conditions.

Soon the URL becomes too long, messy, and difficult to manage.

That is where GET starts to break down.

Loading diagram…
The moment a search outgrows the URL.

2. Why Not Use a Body With GET?

A developer might reasonably think: why not keep the URL clean and put the filters inside the GET body?

Like this:

GET /api/products
Content-Type: application/json
 
{
  "brand": "nike",
  "color": "red",
  "size": 10,
  "priceMax": 50
}

It looks reasonable. It is not a reliable design.

A body on a GET request does not have a clear, standard meaning across the web. Some tools may ignore it. Some proxies may mishandle it. Some caches will not consider it when storing responses.

So even if it works in your local setup, it may behave differently once the request passes through browsers, CDNs, gateways, servers, and production infrastructure.


3. The Common Workaround: Use POST for Search

To avoid long URLs, developers started using POST for searches:

POST /api/products/search
Content-Type: application/json
 
{
  "brand": "nike",
  "color": "red",
  "size": 10,
  "priceMax": 50,
  "delivery": "tomorrow"
}

This works technically. The request body can be large. The JSON is clean. The backend gets all the filters properly.

That is why so many APIs expose endpoints like:

POST /search
POST /query
POST /graphql

Even when they are only fetching data.

But there is a hidden problem: POST does not clearly mean "read-only."

A POST request might create an order, submit a form, charge a card, upload a file, or trigger a workflow.

Because of that, browsers, CDNs, and other systems treat it carefully. They cannot always assume it is safe to retry. They do not naturally cache it like a normal read. They do not know that your POST /search endpoint is only asking a question.

So the API works, but the meaning is not clean. You are using a method designed for "sending something that may change state" to perform a search that only reads data.

That is the architectural mismatch.


4. Why This Matters for Performance

Caching is one of the biggest reasons the web is fast.

When a request is cacheable, a CDN can store the response and serve it again without hitting the main backend every time.

With GET, caching is straightforward because the URL identifies the request:

GET /api/products?color=red

The cache can store the response for that exact URL.

But with POST, the important search details live inside the body. Many systems do not treat POST search requests as simple cacheable reads by default.

So if 10,000 users run the same heavy search, your backend may have to calculate the same result 10,000 times. That means more server load, slower responses, and higher infrastructure cost.

Loading diagram…
Same search, 10,000 times: the cache absorbs it, or your database does.

Developers were stuck with a trade-off:

MethodBenefitProblem
GETCorrect meaning and cache-friendlyBad for large complex queries
POSTSupports large request bodiesHides that the request is read-only

The web needed a better middle ground.


5. Enter QUERY

The new QUERY method gives HTTP a proper way to say:

I am sending a request body, but I am only asking for data.

A QUERY request looks like this:

QUERY /api/products
Content-Type: application/json
Accept: application/json
 
{
  "brand": "nike",
  "color": "red",
  "size": 10,
  "priceMax": 50,
  "delivery": "tomorrow"
}

This is the missing piece.

Like POST, QUERY can carry a structured body. Like GET, QUERY is meant for safe, read-only operations. The request is not supposed to create, update, or delete anything. It simply asks the server to process the query and return a result.

That makes the intent much clearer. You are no longer pretending that a search is a POST. You are using a method that actually describes what the request is doing.


6. QUERY vs GET vs POST

Here is the simple way to think about it:

Use caseBest method
Simple request that fits in the URLGET
Creating, submitting, or triggering somethingPOST
Complex read-only request with a bodyQUERY

For a simple product page:

GET /api/products/123

For creating an order:

POST /api/orders

For a complex product search:

QUERY /api/products

That is the clean separation.

Loading diagram…
Two questions get you to the right method every time.

7. Should You Use QUERY Today?

Not everywhere, and not immediately.

QUERY is new, so frameworks, browsers, CDNs, gateways, and security tools need time to support it properly. In many production systems, POST /search will continue to exist for a while because the existing infrastructure already understands it.

But the idea behind QUERY matters. It gives API designers a better vocabulary.

For years, developers had to choose between long GET URLs and misleading POST searches. QUERY finally gives complex read operations their own proper method.


Final Takeaway

The web has always been built on simple methods:

  • GET to fetch
  • POST to submit
  • PUT and PATCH to update
  • DELETE to remove

But modern applications ask more complex questions than that old model handled cleanly.

That is why QUERY matters. It does not replace GET. It does not replace POST. It fills the awkward gap between them — letting you send large, structured search requests while clearly saying:

This is only a query. Nothing is being changed.