Skip to content

Commit 4ef9955

Browse files
Added QUERY to HTTP method (#114)
* Added query docs * Updated query
1 parent e1d0739 commit 4ef9955

1 file changed

Lines changed: 81 additions & 0 deletions

File tree

src/2-api-design-basics/02-http-methods.adoc

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,85 @@ Both clients were trying to update a single instance of a resource, but little d
296296

297297
Oftentimes an API will only support one of these methods. We *strongly* recommend supporting both, unless you have a very specific reason not to. `PUT` is great for full updates, but `PATCH` is more flexible and can be more efficient for partial updates.
298298

299+
== QUERY: The new kid on the block
300+
301+
The `QUERY` method is a newer addition to HTTP that addresses a specific gap: the need for a safe, idempotent method that can carry a request body.
302+
303+
The problem QUERY solves is straightforward: sometimes you need to send complex query parameters - like filtering criteria, search specifications, or data selection logic - that are too large or complex for a URL query string. Using GET means everything goes in the URL, which suits most cases but does have practical size limits. Using POST works but signals the wrong intent and prevents caching.
304+
305+
QUERY requests are both safe and idempotent, meaning they don't modify server state and can be safely retried or cached.
306+
307+
=== QUERY Examples
308+
309+
Filtering a large dataset with complex criteria:
310+
311+
[source,http]
312+
----
313+
QUERY /feed
314+
Host: api.example.org
315+
Content-Type: application/json
316+
Accept: application/json
317+
318+
{
319+
"search-query": "foo",
320+
"limit": 10,
321+
"sort": {
322+
"price": "desc",
323+
"published": "asc"
324+
},
325+
"filter": [
326+
{
327+
"field": "origin",
328+
"value": "london"
329+
},
330+
{
331+
"field": "destination",
332+
"value": "paris"
333+
},
334+
{
335+
"field": "price",
336+
"value": "60.00",
337+
"operator": "<="
338+
}
339+
]
340+
}
341+
----
342+
343+
=== Accept-Query Header
344+
345+
Servers can advertise support for QUERY using the `Accept-Query` response header, which specifies the query format media types the server accepts.
346+
347+
[source,http]
348+
----
349+
OPTIONS /contacts HTTP/1.1
350+
Host: api.example.org
351+
352+
HTTP/1.1 200 OK
353+
Accept-Query: application/sql, application/json
354+
Allow: GET, POST, QUERY, OPTIONS
355+
----
356+
357+
=== Best Practices for QUERY requests
358+
359+
* Safe and idempotent: Like GET, but with a request body
360+
* Cacheable: Responses can and should be cached when appropriate
361+
* Query in body: The request body contains the query specification, not the URL
362+
* Flexible formats: Supports any query format (SQL, JSONPath, GraphQL, custom DSL, etc.)
363+
* Use Accept-Query: Advertise supported query formats to clients
364+
* Conditional queries: Supports conditional execution with If-Modified-Since and related headers
365+
366+
=== When to Use QUERY
367+
368+
QUERY is ideal when you need to:
369+
370+
* Send complex extremely complex filtering or search criteria that don't fit cleanly in URL parameters
371+
* Query collections with sophisticated selection logic
372+
* Enable caching of query results (unlike POST)
373+
* Signal that the operation is safe and won't modify data
374+
* Support multiple query formats or languages
375+
376+
Note that QUERY is a relatively new addition to HTTP and may not yet be widely supported by all frameworks and infrastructure. Check compatibility before adopting it in production systems.
377+
299378
== Remember
300379

301380
HTTP methods aren't just syntax - they're core to how the web works. Using them correctly makes your API:
@@ -306,3 +385,5 @@ HTTP methods aren't just syntax - they're core to how the web works. Using them
306385
* Easier to maintain and scale
307386

308387
Your choice of HTTP method communicates intent and behavior to both developers and tools, so choose wisely and consistently.
388+
389+

0 commit comments

Comments
 (0)