A Quarkus demo of the HTTP QUERY method defined by RFC 10008 (June 2026), the first new HTTP method since PATCH (2010).
QUERY fills a long-standing gap in HTTP: it is safe and idempotent like GET, but carries request content like POST. That makes it ideal for complex searches whose parameters don't fit comfortably in a URI, while still allowing caching and automatic retries.
The application exposes a small in-memory product catalog at /products and implements the RFC's semantics with plain Jakarta REST. The only extension point needed is a custom @HttpMethod("QUERY") annotation; no framework changes are involved.
| RFC 10008 concept | Where in this project |
|---|---|
Custom QUERY method |
io.jugistanbul.QUERY, a Jakarta REST @HttpMethod("QUERY") annotation |
Query semantics driven by Content-Type (Section 2.1) |
ProductResource accepts both application/json and application/x-www-form-urlencoded query content |
Accept-Query response header (Section 3) |
AcceptQueryFilter advertises the supported media types; also visible on OPTIONS (with Allow: ..., QUERY) |
Location as the equivalent resource (Section 2.2) |
QUERY responses include a Location URI that yields the same result via plain GET |
| Explicit cacheability (Section 2.7) | QUERY responses carry Cache-Control: no-transform, max-age=60 and an ETag derived from the result |
| Conditional requests (Section 2.6) | If-None-Match on an unchanged query yields 304 Not Modified without resending the result |
415 Unsupported Media Type |
Unsupported query content types are rejected |
422 Unprocessable Content |
Well-formed but unprocessable queries (e.g. minPrice > maxPrice) |
| Idempotency | Covered by ProductResourceTest |
- JDK 21 or newer (the Maven wrapper is included, no local Maven needed)
./mvnw quarkus:devThe application starts on http://localhost:8080.
# QUERY with JSON content
curl -i -X QUERY http://localhost:8080/products \
-H 'Content-Type: application/json' \
-d '{"category":"laptop","maxPrice":2000}'
# Same query as form-urlencoded content (as in the RFC's example)
curl -X QUERY http://localhost:8080/products \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'category=accessory&maxPrice=200'
# Re-fetch the same result via the equivalent resource from the Location header
curl 'http://localhost:8080/products?category=laptop&maxPrice=2000'
# Conditional QUERY: repeat the query with the ETag from the previous response
curl -i -X QUERY http://localhost:8080/products \
-H 'Content-Type: application/json' \
-H 'If-None-Match: "<etag-from-previous-response>"' \
-d '{"category":"laptop","maxPrice":2000}'
# -> HTTP/1.1 304 Not Modified
# Discover QUERY support without knowing it in advance
curl -i -X OPTIONS http://localhost:8080/products
# -> Allow: ..., QUERY
# -> Accept-Query: application/json, application/x-www-form-urlencodedA successful QUERY response looks like:
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Accept-Query: application/json, application/x-www-form-urlencoded
Location: http://localhost:8080/products?category=laptop&maxPrice=2000
Cache-Control: no-transform, max-age=60
ETag: "<hash-of-result>"
[{"category":"laptop","id":2,"name":"ThinkPad X1 Carbon","price":1899.00}, ...]
Note: Browsers implementing CORS will send a preflight for QUERY, since it is not a CORS-safelisted method. Server-to-server or CLI clients (like curl) are unaffected.
./mvnw testThe suite covers the filtering logic, both query media types, the error codes (400, 415, 422), the equivalent-resource round trip, the conditional request flow, and a repetition test verifying that QUERY behaves as a safe, idempotent operation.
./mvnw package
java -jar target/quarkus-app/quarkus-run.jarA native executable can be built with ./mvnw package -Dnative (or with -Dquarkus.native.container-build=true to build inside a container without a local GraalVM).