I thought it wouldn't be a terrible idea to open up the GET method to contain a body but according to the original spec the GET body is to be ignored completely. There's also caching which would break because the important bit of the request would live in the stripped body.
I've been sending request body along GET method for years now
Even imagining a QUERY with a large JSON filtering structure, or say an image input as request body, it feels extremely odd to include the request body as part of the cache key. It also implies an unbounded and user-controlled cache key, with the only really meaningful general caching strategy being bitwise compare of the request body (or a hash), which in a hostile scenario implies cache busting would be trivial.
This invokes multiple semantic oddities in one go with obvious difficulties for a very niche use case. If I'm writing a service that needs complex filtering or complex input like an image, any form of caching (e.g. individual data columns of a join, or embeddings keyed by perceptual hashes of a decoded image input) is going to be far away from the HTTP layer and certainly unrelated to the exact bit representation of the request on the wire.
Why even bother trying to capture this in a generic way?
I would be far more inclined to try and capture this caching semantic as a new header for POST. Something like "Vary: request-body" or similar. Perfectly backwards compatible and perfectly ignorable for all but the 0.1% of CDN use cases where the behaviour might turn out useful
I think the name is confusing because the term 'query' is already used to refer to http requests in general.
Just the title of the RFC confused me.
I’ve enjoyed the combination with Range headers for paging, despite this tidbit:
> It is expected that these built-in features will be used instead of HTTP Range Requests
Using the QUERY request as the definition of a set, and Range to retrieve subsets seems very natural.
Generally not a great idea. With some http implementations this is not even possible (for example, fetch)
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/U...
> You cannot include a body with GET requests
And transparent caching might result in weird issues.
HTTP is transfer protocol. It should not ever imply anything at the business level.
Yes REST made it's worst mistake out if it by giving a meaning to the verb.
Yes proxies rule how the body is re-interpreted in spite of the will of the sender (wtf).
But the original RFC states clearly that any verb can be used. This is how WebDav normalised its own.
But playing fancy by introducing a change that all HTTP implementation will have to honor is a very bad and irrational choice.
<form action="..." method="query">
This would avoid the annoying re-submission warnings you're getting if you refresh a page that was returned by a POST form submission, since QUERY is required to be idempotent.I like that we now have a way to not being forced to define Resources when we want to query. It always felt like I was missing something that there could be an infinite, defined-on-the-fly number of Resources for a "part" of a given Resource. Do I really want to define "all cats that sleep more than 20 hours a day and like sunbeams and want to eat breakfast at 3 am" as a Resource? (ok, we all know that is actually the full set of cats). I'm ok that you want to define that as a Resource but in my system, it makes more sense that Cats is the Resource and I just need some accepted way to query.
I like the implementation (again, as just a guy that programs). I don't see how it could have done it better or simpler which probably hides the complexity of getting there.
I also especially appreciate how the spec is written. Opening a spec, I wonder how far I'll get before I don't know what the heck they're talking about (and, again, as just a guy that programs). I don't think it's easy to write a spec that is complete and approachable like this. Really appreciate that.
Exemple:
``` QUERY /search HTTP/1.1 Content-Type: application/json
{ "filters": { "region": "asia", "status": "active" }, "sort": "created_at", "limit": 500 } ```
can answer
``` HTTP/1.1 303 See Other Location: /queries/results/f3a9c1d7 ```
And then you can access later `/queries/results/f3a9c1d7` using a pure GET call, and cache this instead
But I think this would make it better - QUERY before POST means different request types, not just the same with a safety flag.
While the concern is valid, caching is entirely optional at query level, therefore it is totally valid to cache only certain "filters".
Edit: ah, they declare QUERY as "safe" meaning no side effects, for cacheability. My mistake.
The query part of GET's URI is also barely bounded in practice and user-controlled, and is indeed used as part of the cache key (because it's a part of URI), so I am not sure why you raise this objection at all.
Realistically, systems for the public internet will use a secure hash as the cache key so it'll always be the same size. The cache key already includes a URL that can be very long, and an arbitrary set of header values.
/?hash=123456789
In what circles is this the case? I sometimes colloquially refer to a GET request as a query, but definitely not so on a POST, PUT or DELETE.
QUERY has the advantage of getting default behaviour from most proxies (which at least is well behaved even if inefficient). If there are any proxies that just drop QUERY requests, at least they won't silently mangle the request.
This is the same way that instead of improving how HTTP 301 was specified, HTTP 308 was created. It's a pragmatic move.
If method=QUERY were added, there would be a new variety of this weirdness.
Unlike POST, however, the method is explicitly safe and idempotent, allowing
functions like caching and automatic retries to operate.
Essentially, it's for things that are inherently safe/idempotent already (e.g. search or indeed, anything that you don't mind being retried) but require a lot of data passed in the request.I've found some sites that tack on a session ID and if you try to tamper with the URL in any way, it sends you back to "Page 1" really annoys me lol at that point let me skip to any page with your web UI.
I guess it's about resolving the odd semantics of using POST which is not idempotent and thus allowing easier control flow of caches and retrys.
Your perspective is 100% correct if you think at the application-layer, but with a dedicated method, you can have that behaviour out-of-the-box out of your HTTP infrastructure (whether it's at your hyperscaler's router or your apache/nginx/browser whatever) and stop implementing yourself the post-as-a-query edge case.
There is one interesting variant though, which uses state: The client sends a QUERY containing the full query, and the server returns a url usable with GET with which this query can be triggered in the future. Similar to prepared statements in SQL databases.
Using QUERY for GraphQL queries (not mutations) would be a good match. These only read data, but are sometimes bigger than the url length limit.
https://manifold.markets/CollectedOverSpread/when-will-rfc-1...
It feels very pointless and there is no drawback of just using POST
The team will have to wait for a new header and textarea specs to fix the rest of the jank.
This site is so awful lol. Why don’t they update it?
QUERY on the other hand makes sense for cases where the request doesn't cause any state changes on the server, and there is no resource to redirect to.
If we can do QUERY forms, it would be an ideal time to add JSON encoding for forms.
https://mailarchive.ietf.org/arch/msg/tools-discuss/EpoQcVt_...
RFC #s are issued sometime before publication, so they can come out out of order. I would expect 9999, 10001, etc. to show up eventually.
So of 10008 is the first one after 10000, that date is the one to bet on.
> A QUERY request from user agents implementing Cross-Origin Resource Sharing (CORS) will require a "preflight" request, as QUERY does not belong to the set of CORS-safelisted methods (see [FETCH]).
I still don’t get how idempotency can typically be ensured without state. It very much depends on data model and application design. Even side effects like using a user’s lookup quota need to be handled at a higher layer than HTTP (I think?).
just wow, people seem to be having too much money it seems for them to bet over when RFC's are gonna get released.
This isn't even one of the worst offenders on prediction market or even comparable to it but I am just amazed (in a negative manner, surprised? its just strange) by the depth on what people actually bet on these markets.
Comment submission isn't safe, so QUERY can't be used there. And it doesn't suffer from the problem anyways, since HN returns a 3XX on successful submission, so refreshing doesn't show a warning.
i actually agree with you, i don't comprehend why we're adding anything to HTTP like this, it is basically already deprecated. The modern API is WebTransport, if you want to make caching better for WebTransport, do it there.
When it's your client talking to your server you can obviously do whatever you want - it doesn't cause problems until you want to involve third-party code, such as a reverse proxy (such as nginx) or a CDN. This includes proxies your customers may be using.
But what the Query method really targets are things like a graphql query that can be multiple kb for a single query, but only reads data. Sure, it might count against rate limits, trigger logs, etc. But at a conceptual level resubmitting the same query should give the same result (if the data didn't change). And since you are only reading data, resubmitting is safe
If it's not actually idempotent but you're telling the browser it is, of course you may cause bugs. Same as GET.
Well, how is "GET /index.html HTTP/1.1" made idempotent in practice without (additional) state?
Although we could also go with, a proxy shouldn't delete the body, it "should" reject the request outright as ill-formed.
The meta-point I'm making here, which I'm sure will be missed if I don't spell it out, is that if we're going to talk about what "should" be done when it is explicily out of the scope of a standard, there's no way around the fact that there are multiple completely sensible ways to extend the standard and there's every reason to expect that in the real world people aren't going to agree. Sometimes they manage to, but even then often quite imperfectly. Our human intuitions that standards are something that are "built" is perhaps not wrong, but you can also productively look at standards as taking the raw material of all possible things two systems could send to each other and removing possibilities. If you reach into a space that has been explicitly removed, you can't expect everyone else to do so in exactly the same way you will.
Interesting thing actually. Seems similar to the trend in South Korea recently where you can online shop to get the thrill of shopping but you aren't actually paying with money.
But I am unsure of the overlap between manifold and polymarket/kalshi. I imagine that some might win in manifold and try to bet on polymarket to win "real" money which ends up being a bit gambling-esque.
But good for manifold for atleast not playing with real money but rather points like this. I would argue that Manifold might be better than polygon/kalshi in terms of net positive outcome of its existence for the world perhaps.
You simply can't base64 large payloads and you're stuck with workarounds.
For a very long time, the spec did not say it's illegal. In fact, RFC 2616 (that has been defining the HTTP/1.1 for 15 years) says that
A message-body MUST NOT be included in
a request if the specification of the request method (section 5.1.1)
does not allow sending an entity-body in requests. A server SHOULD
read and forward a message-body on any request; if the request method
does not include defined semantics for an entity-body, then the
message-body SHOULD be ignored when handling the request.
but if you go into the section that describes the semantics of a GET request, well — that section says nothing at all whether a GET request is allowed or not to have a message-body. So it's not prohibited, and the servers should simply ignore it when processing it (and proxies should forward it up).There is an overlap between Manifold and Polymarket/Kalshi. At the very least, Polymarket is more liquid, which creates opportunities for arbitrage and incentives for Manifold users to follow Polymarket. There is something at stake on Manifold itself if you choose to pursue it. There have been ways to convert mana to charitable donations (to your preferred charity), tickets to Manifest (the Manifold conference), and also merch and now prize drawings. Mana is like HN karma in that being at the top gives you status and bragging rights and suggests technical competence.
Are we seriously ok with linking the RFC as source while providing a statement that doesn't match? RFC does matter.
One can infer from the RFC that you can reasonably expect many implementations to fail beyond 8000 characters, and that there are no guarantees up to that either.
True, the RFC doesn't specify a limit, but it does clearly indicate that it's not unbounded, nor should you expect it to be.
This specification defines the QUERY method for HTTP. A QUERY requests that the request target process the enclosed content in a safe and idempotent manner and then respond with the result of that processing. This is similar to POST requests, but QUERY requests can be automatically repeated or restarted without concern for partial state changes.¶
This is an Internet Standards Track document.¶
This document is a product of the Internet Engineering Task Force (IETF). It represents the consensus of the IETF community. It has received public review and has been approved for publication by the Internet Engineering Steering Group (IESG). Further information on Internet Standards is available in Section 2 of RFC 7841.¶
Information about the current status of this document, any errata, and how to provide feedback on it may be obtained at https://www.rfc-editor.org/info/rfc10008.¶
Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
This specification defines the HTTP QUERY request method as a means of making a safe, idempotent request (Section 9.2 of [HTTP]) that encloses a representation describing how the request is to be processed by the target resource.¶
A common query pattern is:¶
However, when the data conveyed is too voluminous to be encoded in the request's URI, this pattern becomes problematic:¶
As an alternative to using GET, many implementations make use of the HTTP POST method to perform queries, as illustrated in the example below. In this case, the input to the query operation is passed as the request content as opposed to using the request URI's query component.¶
A typical use of HTTP POST for requesting a query is:¶
In this variation, however, it is not readily apparent -- without specific knowledge of the resource and server to which the request is being sent -- that a safe, idempotent query is being performed.¶
The QUERY method provides a solution that spans the gap between the use of GET and POST, with the example above being expressed as:¶
As with POST, the input to the query operation is passed as the content of the request rather than as part of the request URI. Unlike POST, however, the method is explicitly safe and idempotent, allowing functions like caching and automatic retries to operate.¶
Recognizing the design principle that any important resource ought to be identified by a URI, this specification describes how a server can assign URIs to both the query itself or to a specific query result, for later use in a GET request.¶
Summarizing:¶
Table 1: Summary of Relevant Method Properties
| GET | QUERY | POST | |
|---|---|---|---|
| Safe | yes | yes | potentially no |
| Idempotent | yes | yes | potentially no |
| URI for query itself | yes (by definition) | optional (Location response field) | no |
| URI for query result | optional (Content-Location response field) | optional (Content-Location response field) | optional (Content-Location response field) |
| Cacheable | yes | yes | yes, but only for future GET or HEAD requests |
| Content (body) | "no defined semantics" | expected (semantics per target resource) | expected (semantics per target resource) |
This document uses terminology defined in Section 3 of [HTTP].¶
Furthermore, it uses the terms URI query parameter for parameters in the query component of a URI (Section 4.2.2 of [HTTP]) and query content for the request content (Section 6.4 of [HTTP]) of a QUERY request.¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
The QUERY method is used to initiate a server-side query. Unlike the GET method, which requests a representation of the resource identified by the target URI (as defined by Section 7.1 of [HTTP]), the QUERY method is used to ask the target resource to perform a query operation within the scope of that target resource.¶
The content of the request and its media type define the query. The origin server determines the scope of the operation based on the target resource.¶
Servers MUST fail the request if the Content-Type request field ([HTTP], Section 8.3) is missing or is inconsistent with the request content.¶
As for all HTTP methods, the target URI's query part takes part in identifying the resource being queried. Whether and how it directly affects the result of the query is specific to the resource and is out of scope for this specification.¶
QUERY requests are safe with regard to the target resource ([HTTP], Section 9.2.1); that is, the client does not request or expect any change to the state of the target resource. This does not prevent the server from creating additional HTTP resources through which additional information can be retrieved (see Sections 2.3 and 2.4).¶
Furthermore, QUERY requests are idempotent ([HTTP], Section 9.2.2); they can be retried or repeated when needed, for instance, after a connection failure.¶
As per Section 15.3 of [HTTP], a 2xx (Successful) response code signals that the request was successfully received, understood, and accepted.¶
In particular, a 200 (OK) response indicates that the query was successfully processed and the results of that processing are enclosed as the response content.¶
The equivalent resource for any given QUERY request is a resource that responds to GET requests, represents that QUERY request and its target, and takes both message content and metadata into account (Section 6 of [HTTP]). In particular, this includes representation metadata (Section 8 of [HTTP]) such as the content's media type.¶
In other words, the equivalent resource is derived from the resource implementing QUERY by incorporating the request content.¶
The term equivalent resource is used as a means to define behavior for other HTTP aspects, such as selected representations. Servers can but do not have to assign URIs to these resources (see Section 1.1 of [URI]). If they do so, these resources will become accessible for GET requests.¶
A successful response (2xx, Section 15.3 of [HTTP]) can include a Content-Location header field containing an identifier for a resource corresponding to the results of the operation; see Section 8.7 of [HTTP] for details. This represents a claim from the server that a client can send a GET request for the indicated URI to retrieve the results of the query operation just performed. The indicated resource might be temporary.¶
See Appendix A.4.1 for an example.¶
A server can assign a URI to the equivalent resource (Section 2.2) of a QUERY request. If the server does so, the URI of that resource can be included in the Location header field of the 2xx response (see Section 10.2.2 of [HTTP]). This represents a claim that a client can send a GET request to the indicated URI to repeat the query operation just performed without resending the query content. This resource's URI might be temporary; if a future request fails, the client can retry using the original QUERY request target and the previously submitted content.¶
See Appendix A.4.2 for an example.¶
In some cases, the server may choose to respond indirectly to the QUERY request by redirecting the user agent to a different URI (see Section 15.4 of [HTTP]).¶
A response with either status codes 301 (Moved Permanently, [HTTP], Section 15.4.2) or 308 (Permanent Redirect, [HTTP], Section 15.4.9) indicates that the target resource has permanently moved to a different URI referenced by the Location response field ([HTTP], Section 10.2.2). Likewise, a response with either status codes 302 (Found, [HTTP], Section 15.4.3) or 307 (Temporary Redirect, [HTTP], Section 15.4.8) indicates that the target resource has temporarily moved. In all four cases, the server is suggesting that the user agent can accomplish its original QUERY request by sending a similar QUERY request to the new target URI referenced by the Location.¶
Note that the exceptions for redirecting a POST as a GET request after a 301 or 302 response do not apply to QUERY requests.¶
A response to QUERY with the status code 303 (See Other, Section 15.4.4 of [HTTP]) indicates that the original query can be accomplished via a normal retrieval request on the URI referenced by the Location response field ([HTTP], Section 10.2.2). For HTTP, this means sending a GET request to the new target URI, as illustrated by the example in Appendix A.4.3.¶
The selected representation (Section 3.2 of [HTTP]) of a QUERY request is the same as for a GET request to the equivalent resource (Section 2.2) of that QUERY request.¶
A conditional QUERY requests that the selected representation (i.e., the query results after any content negotiation) be returned in the response only under the circumstances described by the conditional header field(s), as defined in Section 13 of [HTTP].¶
See Appendix A.5 for examples.¶
The response to a QUERY method is cacheable; a cache MAY use it to satisfy subsequent QUERY requests as per Section 4 of [HTTP-CACHING].¶
The cache key for a QUERY request (Section 2 of [HTTP-CACHING]) MUST incorporate the request content (Section 6 of [HTTP-CACHING]) and related metadata (Section 8 of [HTTP]).¶
To improve cache efficiency, caches MAY remove semantically insignificant differences from request content and related metadata first. For instance, by:¶
Note that any such transformation is performed solely for the purpose of generating a cache key; it does not change the request itself.¶
Clients can indicate, using the "no-transform" cache directive (Section 5.2.1.6 of [HTTP-CACHING]) that they wish that no such transformation happens (but note that this directive is just advisory).¶
Note that caching QUERY method responses is inherently more complex than caching responses to GET, as complete reading of the request's content is needed in order to determine the cache key. If a QUERY response supplies a Location response field (Section 2.4) to indicate a URI for an equivalent resource (Section 2.2), clients can switch to GET for subsequent requests, thereby simplifying processing.¶
The semantics of Range Requests for QUERY are identical to those for GET, as defined in Section 14 of [HTTP]. Byte Range Requests (the only range unit defined at the time of writing), however, offer little value for the results of a QUERY request.¶
Query formats often define their own way of limiting or paging through result sets, such as with "FETCH FIRST ... ROWS ONLY" in SQL. It is expected that these built-in features will be used instead of HTTP Range Requests.¶
The "Accept-Query" response header field can be used by a resource to directly signal support for the QUERY method while identifying the specific query format media type(s) that may be used.¶
Accept-Query contains a list of media ranges (Section 12.5.1 of [HTTP]) using "Structured Fields" syntax [STRUCTURED-FIELDS]. Media ranges are represented by a List Structured Header Field of either Tokens or Strings, containing the media range value without parameters.¶
Media type parameters, if any, are mapped to Structured Field Parameters with the String or Token type. The choice of Token versus String is semantically insignificant. That is, recipients MAY convert Tokens to Strings, but MUST NOT process them differently based on the received type.¶
Media types do not exactly map to Tokens; for instance, they allow a leading digit. In cases like these, the String format needs to be used.¶
The only supported uses of wildcards are "*/*", which matches any type, or "xxxx/*", which matches any subtype of the indicated type.¶
The order of types listed in the field value is not significant.¶
The value of the Accept-Query field applies to every URI on the server that shares the same path; in other words, the query component is ignored. If requests to the same resource return different Accept-Query values, the most recently received fresh value (per Section 4.2 of [HTTP-CACHING]) is used.¶
For example:¶
Although the syntax for this field appears to be similar to other fields, such as "Accept" (Section 12.5.1 of [HTTP]), it is a Structured Field and thus MUST be processed as specified in Section 4 of [STRUCTURED-FIELDS].¶
The QUERY method is subject to the same general security considerations as all HTTP methods as described in [HTTP].¶
It can be used as an alternative to passing request information in the URI (e.g., in the query component). This is preferred in some cases, as the URI is more likely to be logged or otherwise processed by intermediaries than the request content. In other cases, where the query contains sensitive information, the potential for logging of the URI might motivate the use of QUERY over GET.¶
If a server creates a temporary resource to represent the results of a QUERY request (e.g., for use in the Location or Content-Location field), assigns a URI to that resource, and the request contains sensitive information that cannot be logged, then that URI SHOULD be chosen such that it does not include any sensitive portions of the original request content.¶
Caches that normalize QUERY content incorrectly or in ways that are significantly different from how the resource processes the content can return an incorrect response if normalization results in a false positive.¶
A QUERY request from user agents implementing Cross-Origin Resource Sharing (CORS) will require a "preflight" request, as QUERY does not belong to the set of CORS-safelisted methods (see [FETCH]).¶
IANA has added the QUERY method to the "Hypertext Transfer Protocol (HTTP) Method Registry" at <http://www.iana.org/assignments/http-methods> (see Section 16.3.1 of [HTTP]).¶
Table 2: QUERY Method Definition
| Method Name | Safe | Idempotent | Specification |
|---|---|---|---|
| QUERY | yes | yes | Section 2 of RFC 10008 |
IANA has added the Accept-Query field to the "Hypertext Transfer Protocol (HTTP) Field Name Registry" at <https://www.iana.org/assignments/http-fields> (see Section 16.1.1 of [HTTP]).¶
Table 3: Accept-Query Field Definition
| Field Name | Status | Structured Type | Reference | Comments |
|---|---|---|---|---|
| Accept-Query | permanent | List | Section 3 of RFC 10008 |
[HTTP]
Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP Semantics", STD 97, RFC 9110, DOI 10.17487/RFC9110, June 2022, <https://www.rfc-editor.org/info/rfc9110>.
[HTTP-CACHING]
Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP Caching", STD 98, RFC 9111, DOI 10.17487/RFC9111, June 2022, <https://www.rfc-editor.org/info/rfc9111>.
[RFC2119]
Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, <https://www.rfc-editor.org/info/rfc2119>.
[RFC8174]
Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, <https://www.rfc-editor.org/info/rfc8174>.
[STRUCTURED-FIELDS]
Nottingham, M. and P. Kamp, "Structured Field Values for HTTP", RFC 9651, DOI 10.17487/RFC9651, September 2024, <https://www.rfc-editor.org/info/rfc9651>.
[URI]
Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, DOI 10.17487/RFC3986, January 2005, <https://www.rfc-editor.org/info/rfc3986>.
[FETCH]
WHATWG, "FETCH", WHATWG Living Standard, <https://fetch.spec.whatwg.org>. Commit snapshot: <https://fetch.spec.whatwg.org/commit-snapshots/3bab31a55154bda73f25b45a23df718616f2f64e/>.
[RFC3253]
Clemm, G., Amsden, J., Ellison, T., Kaler, C., and J. Whitehead, "Versioning Extensions to WebDAV (Web Distributed Authoring and Versioning)", RFC 3253, DOI 10.17487/RFC3253, March 2002, <https://www.rfc-editor.org/info/rfc3253>.
[RFC4918]
Dusseault, L., Ed., "HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)", RFC 4918, DOI 10.17487/RFC4918, June 2007, <https://www.rfc-editor.org/info/rfc4918>.
[RFC5323]
Reschke, J., Ed., Reddy, S., Davis, J., and A. Babich, "Web Distributed Authoring and Versioning (WebDAV) SEARCH", RFC 5323, DOI 10.17487/RFC5323, November 2008, <https://www.rfc-editor.org/info/rfc5323>.
[RFC6838]
Freed, N., Klensin, J., and T. Hansen, "Media Type Specifications and Registration Procedures", BCP 13, RFC 6838, DOI 10.17487/RFC6838, January 2013, <https://www.rfc-editor.org/info/rfc6838>.
[RFC8259]
Bray, T., Ed., "The JavaScript Object Notation (JSON) Data Interchange Format", STD 90, RFC 8259, DOI 10.17487/RFC8259, December 2017, <https://www.rfc-editor.org/info/rfc8259>.
[RFC9535]
Gössner, S., Ed., Normington, G., Ed., and C. Bormann, Ed., "JSONPath: Query Expressions for JSON", RFC 9535, DOI 10.17487/RFC9535, February 2024, <https://www.rfc-editor.org/info/rfc9535>.
[URL]
WHATWG, "URL", WHATWG Living Standard, <https://url.spec.whatwg.org>. Commit snapshot: <https://url.spec.whatwg.org/commit-snapshots/52526653e848c5a56598c84aa4bc8ac9025fb66b/>.
[XSLT]
Kay, M., Ed., "XSL Transformations (XSLT) Version 3.0", W3C Recommendation, 8 June 2017, <https://www.w3.org/TR/2017/REC-xslt-30-20170608/>. Latest version available at https://www.w3.org/TR/xslt-30/.
The examples below are for illustrative purposes only; if one needs to send queries that are actually this short, it is likely better to use GET.¶
The media type used in most examples is "application/x-www-form-urlencoded" (as used in POST requests from browser user clients, defined in "application/x-www-form-urlencoded" in [URL]). The Content-Length fields have been omitted for brevity.¶
Below is a simple query with a direct response:¶
Response:¶
A simple way to discover support for QUERY is provided by the OPTIONS (Section 9.3.7 of [HTTP]) method:¶
Response:¶
The Allow response field (Section 10.2.1 of [HTTP]) denotes the set of supported methods on the specified resource.¶
There are alternatives to the use of OPTIONS. For instance, a QUERY request can be tried without prior knowledge of server support. The server would then either process the request, or it could respond with a 4xx status such as 405 (Method Not Allowed, Section 15.5.6 of [HTTP]), including the Allow response field.¶
The discovery of supported media types for QUERY is possible via the Accept-Query response field (Section 3):¶
Response:¶
Responses to which request methods will contain Accept-Query will depend on the resource being accessed.¶
An alternative to checking Accept-Query would be to make a QUERY request, and then -- in case of a 4xx status such as a 415 response (Unsupported Media Type, Section 15.5.16 of [HTTP]) -- to inspect the Accept response field (Section 12.5.1 of [HTTP]):¶
As described in Sections 2.3 and 2.4, the Content-Location and Location response fields in success responses (2xx, Section 15.3 of [HTTP]) provide a way to identify alternate resources that will respond to GET requests, either for the received result of the request or for future requests to perform the same operation. Going back to the example from Appendix A.1:¶
Response:¶
The Content-Location response field received above identifies a resource holding the result for the QUERY response it appeared on:¶
Response:¶
Note that there is no guarantee that the server will implement this resource indefinitely, so, after an error response, the client would need to redo the original QUERY request in order to obtain a new alternative location.¶
The Location response field identifies a resource that will respond to GET with a current result for the same process and parameters as the original QUERY request.¶
In this example, one entry was removed at 2024-11-17T16:12:01Z (as indicated in the Last-Modified field), so the response only contains two entries:¶
Assuming that the server still exposes the resource and that there was no change in the query result, a subsequent conditional GET request with the following:¶
would result in a 304 (Not Modified) response (Section 15.4.5 of [HTTP]).¶
Servers can send "indirect" responses (Section 2.5) using the status code 303 (See Other, Section 15.4.4 of [HTTP]).¶
Given the request at the beginning of Appendix A.4, a server might respond with:¶
This is similar to including Location on a direct response, except that no result for the query is returned. This allows the server to only generate or reuse an alternative resource. This resource could then be used as shown in Appendix A.4.2.¶
Consider a resource implementing QUERY that supports "application/sql" and "application/xslt+xml" [XSLT] as request media types, and which can generate responses as "text/csv". The data set being queried contains RFC document information, and the query returns information grouped by decade:¶
Response:¶
Here, the server has assigned the path "/stored-queries/4815162342" to the equivalent resource (Section 2.4) for subsequent use with GET.¶
Later on, the client repeats the query, but specifies that results should only be returned when changed:¶
The data being queried did not change, therefore the server responds with:¶
As the server identified a URI for the equivalent resource, that resource can be accessed with GET. In particular, this avoids resending the query request's content:¶
Here, the state of the data set indeed changed, so new content is returned:¶
(Note the change in the row for this decade.)¶
The diagrams below illustrate the use of conditional requests and how they can differ when a URI is assigned to the equivalent resource (and when the client is taking advantage of it). The fictitious field name "Validator" is used for demonstration purposes.¶
Client Resource QUERY with content 200 OK Validator: foo QUERY with content (conditional on 'foo') 304 Not Modified Validator: foo State Change QUERY with content (conditional on 'foo') 200 OK Validator: bar
Figure 1: Data Flow with QUERY Only
Client Resource QUERY with content Equivalent Resource (generates /xyz) 200 OK Validator: foo Location: /xyz GET (conditional on 'foo') 304 Not Modified Validator: foo State Change GET (conditional on 'foo') 200 OK Validator: bar
Figure 2: Data Flow with GET to Equivalent Resource
The following examples show requests on a JSON-shaped [RFC8259] database of RFC errata.¶
The request below uses eXtensible Stylesheet Language Transformations (XSLT) to extract errata information summarized per year and the defined errata types.¶
Response:¶
Note the Accept-Query response field indicating that another query format, JSONPath [RFC9535], is supported as well. The request below would report the identifiers of all rejected errata submitted since 2024:¶
Response:¶
The "Hypertext Transfer Protocol (HTTP) Method Registry" (<http://www.iana.org/assignments/http-methods>) already contains three other methods with the properties "safe" and "idempotent": "PROPFIND" [RFC4918], "REPORT" [RFC3253], and "SEARCH" [RFC5323].¶
It would have been possible to reuse any of these, updating it in a way that it matches what this specification defines as the new method "QUERY". Indeed, the early stages of this specification used "SEARCH".¶
The method name "QUERY" ultimately was chosen because:¶
We thank all members of the HTTP Working Group for their ideas, reviews, and feedback.¶
The following individuals deserve special recognition: Carsten Bormann, Mark Nottingham, Martin Thomson, Michael Thornburgh, Roberto Polli, Roy Fielding, and Will Hawkins.¶
Ashok Malhotra participated in early discussions leading to this specification:¶
Ashok Malhotra
Discussion on this HTTP method was reopened by Asbjørn Ulsberg during the HTTP Workshop in 2019:¶
Asbjørn Ulsberg
Julian Reschke
greenbytes GmbH
Hafenweg 16
48155 Münster
Germany
James M Snell
Cloudflare
Mike Bishop
Akamai