HTTP Just Got a New Method: What Is the QUERY Method?
.png)
HTTP Just Got a New Method: What Is the QUERY Method?
For years, developers have faced an interesting API design problem.
If we want to retrieve data, we normally use GET.
GET /products?category=books&limit=20
This works perfectly for simple queries.
But what happens when the query becomes complex?
Imagine filtering products by:
- Multiple categories
- Price range
- Brands
- Ratings
- Availability
- Location
- Sorting
- Pagination
Putting all of this into a URL can become difficult to read, maintain and sometimes even impractical.
The common alternative has been to use POST with a JSON body.
But that creates another problem: we are using POST for something that is actually a read-only query.
This is where the new HTTP QUERY method comes in.
The HTTP QUERY method was standardized in RFC 10008 in June 2026. It is designed for safe, idempotent queries that can carry query information in the request body.
The Problem With GET
For a simple search, GET is perfect:
GET /products?category=books
But consider a complex query:
{
"categories": ["books", "electronics"],
"price": {
"min": 100,
"max": 5000
},
"brands": ["Sony", "Samsung"],
"rating": {
"min": 4
},
"inStock": true
}
Trying to convert this entire structure into a URL makes the API difficult to read and maintain.
You could end up with something like:
/products?category=books,electronics&minPrice=100&maxPrice=5000&brands=Sony,Samsung&rating=4&inStock=true
Real enterprise applications can have much more complicated queries.
There is also another consideration: URLs can be recorded by browsers, proxies, load balancers, web servers and monitoring systems. Putting large or sensitive query information into a URL may therefore create additional exposure.
Why Not Just Use POST?
The traditional solution is:
POST /products/search
Content-Type: application/json
with a request body:
{
"categories": ["books", "electronics"],
"price": {
"min": 100,
"max": 5000
}
}
This solves the URL problem because the query can be placed inside the request body.
But semantically, we are saying:
POST
while the actual operation is:
READ / SEARCH
POST is not defined as a safe, idempotent query method like GET. This difference can matter for caching, retries, proxies, API gateways and HTTP infrastructure.
Enter HTTP QUERY
The new method gives API designers another option:
QUERY /products HTTP/1.1
Content-Type: application/json
{
"categories": ["books", "electronics"],
"price": {
"min": 100,
"max": 5000
},
"brands": ["Sony", "Samsung"],
"inStock": true
}
Now the meaning is much clearer.
The request is explicitly a QUERY.
The complex query can live inside the request body while the HTTP method communicates that this is a safe, idempotent query operation.
QUERY Is Not "GET With a Body"
This is an important distinction.
You may wonder:
Why didn't HTTP simply allow GET requests to have a body?
The problem is that GET request content does not have generally defined semantics in HTTP.
QUERY explicitly defines the request content as the query.
So conceptually:
GET + Body
does not have the same standardized meaning as:
QUERY + Body
GET vs POST vs QUERY
| Feature | GET | POST | QUERY |
|---|---|---|---|
| Designed for retrieval | Yes | Not specifically | Yes |
| Request body | No defined semantics | Yes | Yes |
| Safe | Yes | Not generally | Yes |
| Idempotent | Yes | Not generally | Yes |
| Complex query body | No | Yes | Yes |
| Cacheable | Yes | Different semantics | Yes |
A Real-World Example
Imagine an employee search API.
A simple request could be:
GET /employees?department=engineering
That's perfectly fine.
But an enterprise search might require:
{
"departments": ["engineering", "product"],
"locations": ["Hyderabad", "Bangalore"],
"experience": {
"min": 5
},
"skills": ["PHP", "MySQL", "Redis"],
"status": "active",
"sort": {
"field": "experience",
"direction": "desc"
},
"page": 1,
"limit": 50
}
With QUERY:
QUERY /employees
Content-Type: application/json
followed by the JSON body.
The URL identifies the resource, while the request body describes exactly what we want to search.
What About Caching?
This is one of the interesting aspects of QUERY.
QUERY is defined as cacheable.
A caching system needs to distinguish between different queries.
For example:
QUERY /employees
{
"department": "engineering"
}
and:
QUERY /employees
{
"department": "finance"
}
are obviously different queries.
Conceptually, the request content becomes part of determining the cached result.
Therefore, the same URL with different query bodies can produce different cached representations.
What About Retries?
QUERY is also defined as idempotent.
Idempotency is especially useful in distributed systems.
Imagine:
Client
|
| QUERY
v
Server
|
X Network failure
If the client doesn't know whether the request reached the server, an idempotent query can potentially be retried.
This is particularly useful when temporary network failures occur.
When Should We Use QUERY?
I would not replace every GET request with QUERY.
For simple requests:
GET /users/123
GET is still the obvious choice.
For simple filtering:
GET /products?category=books
GET is also perfectly reasonable.
QUERY becomes interesting when the read query itself becomes complex.
Simple Read
|
v
GET
Complex Read
|
v
QUERY
Create / Update
|
v
POST / PUT / PATCH
Is QUERY Ready for Production Everywhere?
Not necessarily.
The standard is new, so support across browsers, frameworks, proxies, CDNs, API gateways and other infrastructure is still evolving.
Before using QUERY in production, test your complete infrastructure:
Client
|
v
CDN
|
v
Load Balancer
|
v
Web Server
|
v
Application
|
v
Database
Every layer needs to correctly handle the new HTTP method.
For existing APIs, there is no reason to immediately replace working POST-based search endpoints.
For new API designs, however, QUERY is definitely worth understanding and experimenting with.
How Would This Look in PHP?
A PHP application can inspect the HTTP method:
<?php
$method = $_SERVER['REQUEST_METHOD'];
if ($method === 'QUERY') {
$body = file_get_contents('php://input');
$query = json_decode($body, true);
// Validate query
// Execute database search
// Return JSON response
}
The exact implementation will depend on your PHP framework and web-server configuration.
The important idea is:
HTTP QUERY
|
v
Request Body
|
v
Validate Query
|
v
Execute Search
|
v
Return Result
The Bigger Idea
The interesting thing about QUERY isn't simply that HTTP has gained another method.
It fills a specific gap.
GET: Great for simple reads, but complex queries can make URLs difficult to manage.
POST: Great for request bodies, but it doesn't specifically communicate a safe, idempotent read-only query.
QUERY: Complex request body + Safe + Idempotent + Cacheable.
That is the real value of the new method.
Final Thoughts
HTTP QUERY is an interesting addition to the HTTP ecosystem because it gives API designers a proper semantic option for complex read-only operations.
Instead of choosing between a complicated GET URL or a POST request being used as a search operation, we now have another option:
QUERY /employees
with the query represented cleanly in the request body.
QUERY will not replace GET or POST. Instead, it provides another tool for a specific API design problem.
A practical way to think about it is:
Simple read → GET
Complex read → QUERY
Create / Update → POST / PUT / PATCH
As the ecosystem starts supporting QUERY, it will be interesting to see how API gateways, browsers, CDNs, frameworks and backend technologies adopt it.
For backend developers, this is definitely a new HTTP feature worth experimenting with.
What's Next?
In the next article, I'll try the new HTTP QUERY method with a real PHP API and show:
- How to send a QUERY request
- How PHP receives the request body
- How to build a QUERY endpoint
- How to test QUERY using cURL
- How caching works
- What happens when a server doesn't support QUERY
Author: Santosh Chakraborty
Topics: HTTP, REST API, API Design, PHP, Backend Engineering, Web Development
Reference: RFC 10008 — The HTTP QUERY Method