⚡ A New HTTP Verb for Developers
The QUERY method (RFC 10008, June 2026) solves a long‑standing pain point: sending complex request bodies safely and cacheably without abusing GET or POST.
Because QUERY is safe and idempotent, if a network drop happens, the client can automatically retry the request without risk of duplicating side effects — a major architectural win.
The Problem with GET and POST
GET Example (Fails with Complex Filters)
GET /api/products?category=electronics&tags=wireless,sale,new-arrival&price_min=100&price_max=1000&sort=rating_desc&page=2&limit=20&brand=Sony|Samsung&in_stock=true&discount_gte=10 HTTP/1.1
Host: shop.com
Enter fullscreen mode Exit fullscreen mode
- Too long → URLs hit browser/server length limits.
- Leaky → Query strings show up in logs, browser history, and monitoring tools.
-
Awkward encoding → Nested conditions (
AND/OR) are hard to represent.
POST Example (Breaks Caching)
POST /api/products/search HTTP/1.1
Host: shop.com
Content-Type: application/json
{
"category": "electronics",
"tags": ["wireless", "sale", "new-arrival"],
"price_range": { "min": 100, "max": 1000 }
}
Enter fullscreen mode Exit fullscreen mode
- Not cacheable → POST responses aren’t cached by browsers or CDNs.
- Wrong semantics → POST is meant for creating resources, not fetching.
🚀 The Solution: QUERY
QUERY combines the best of both worlds: request body support like POST, but safe and cacheable like GET.
📦 Example: Advanced Product Search
{
"category": "electronics",
"tags": ["wireless", "sale", "new-arrival"],
"price_range": { "min": 100, "max": 1000 },
"sort": { "field": "rating", "order": "desc" },
"pagination": { "page": 2, "limit": 20 },
"conditions": {
"or": [
{ "brand": "Sony" },
{ "brand": "Samsung" }
],
"and": [
{ "in_stock": true },
{ "discount": { "gte": 10 } }
]
}
}
Enter fullscreen mode Exit fullscreen mode
QUERY Request
QUERY /api/products HTTP/1.1
Host: shop.com
Content-Type: application/json
Accept: application/json
{ ...payload above... }
Enter fullscreen mode Exit fullscreen mode
📊 Core Comparison Matrix
Metric GET POST QUERY Intended Use Simple fetch Create data Complex fetch Request Body ❌ No ✅ Yes ✅ Yes Safe & Idempotent ✅ Yes ❌ No ✅ Yes Cacheable ✅ Yes ❌ No ✅ Yes Retry on Drop ❌ Risky ❌ Risky ✅ Safe URI for Query ✅ Always ❌ No ⚠️ Optional viaLocation
URI for Result
⚠️ Optional
⚠️ Optional
⚠️ Optional via Content-Location
Discovery
❌ No
❌ No
✅ Accept-Query
Conditional Requests
✅ Yes
❌ No
✅ Yes
Redirection
✅ Yes
✅ Yes
✅ Yes (QUERY→QUERY or GET)
🔧 Real-World Code Examples
Frontend (QUERY with fetch):
async function searchProducts(filters) {
const response = await fetch('https://shop.com/api/products', {
method: 'QUERY',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(filters)
});
return response.json();
}
Enter fullscreen mode Exit fullscreen mode
Backend (Express.js):
const express = require('express');
const app = express();
app.use(express.json());
app.all('/api/products', (req, res, next) => {
if (req.method !== 'QUERY') return next();
const filters = req.body;
const products = db.findProducts(filters);
res.setHeader('Cache-Control', 'public, max-age=3600');
res.json(products);
});
Enter fullscreen mode Exit fullscreen mode
🌐 CDN Support for QUERY with Body
RFC 10008 requires caches to incorporate both the request target and the body into cache keys:
Cache Key = Path + Body Hash
Path: /api/products
Body: {"category":"electronics","tags":["sale"]}
Body Hash: abcd1234
Final Key: /api/products:abcd1234
Enter fullscreen mode Exit fullscreen mode
- Cloudflare → Cache rules + body hash
- Akamai → EdgeWorkers extend cache keys
-
Fastly → VCL:
set req.hash += req.body; - AWS CloudFront → Lambda@Edge workaround (rewrite QUERY → GET + body hash)
- Google Cloud CDN → Proxy QUERY through Cloud Functions until native support arrives
🔑 RFC 10008 Extra Features
-
Discovery → Use
OPTIONSor theAccept-Queryheader to check if a resource supports QUERY - Location Header (URI for Query) → Server may assign a URI representing the query definition
- Content-Location Header (URI for Result) → Server may assign a URI representing the result set
-
Conditional Requests → QUERY supports
ETagandIf-Modified-Sincefor cache validation - Redirection → QUERY can be redirected but must remain QUERY or map to GET
- Security → QUERY avoids leaking sensitive data in URIs, but servers must handle generated URIs carefully
❓ FAQ Highlights
- 🛠️ Frameworks → Express, Django, Spring, and FastAPI don’t yet have
app.query(), but you can intercept QUERY as a raw method string - 🌐 Browsers → All major browsers allow sending QUERY via
fetch; tooling may still show it as a custom verb - 📊 Monitoring → Grafana/Prometheus don’t yet classify QUERY; treat it as a custom verb in logs until native support arrives
✨ Closing Thoughts
The QUERY method (RFC 10008, June 2026) is a true architectural upgrade:
- Safe, idempotent, cacheable
- Supports complex request bodies with arrays, sorting, pagination, and nested conditions
- Enables automatic retries after network drops
- Works with CDNs when cache keys include body hashes
- Adds discovery, conditional requests, redirection, and URI assignment for queries/results
👉 For full details, see the official spec: RFC 10008 – The HTTP QUERY Method
답글 남기기