QUERY should describe use of Content-Location field
@reschke mentioned in #1552 that there should be a way for the server to indicate a GET-able equivalent to the query if one exists; this has the benefit of being more easily cacheable by intermediaries which don't understand QUERY.
Based on SEMANTICS, I think the right mechanism for this would be Content-Location. A server can optionally indicate the GET-able location of the query to which it is responding.
Another approach would be to return 201 Created along with a Location header. To my eye, that more clearly communicates that the URL is pointing at a new resource for the query, rather than for the content of this particular result representation.
The idea that you might "create" a resource like this is a little strange. Presumably, the same QUERY, when repeated, will "create" the same URL.
Still, the semantic does fit fairly neatly and people are well used to the general pattern. And "Created" is just the name; the semantic is a pretty good fit.
I went to start a PR for this, but saw that the spec already includes an example that uses 303 (See Other) for this pattern.
That avoids the counterintuitive aspect of an idempotent method creating something. I wonder just a little bit about whether the relationship between the query presented and the ongoing state of that resource is clearly stated enough, but I suspect it's no worse than any other solution discussed.
So I think we can close this with no action, if giving an example is adequate?
Not sure. It implies an additional roundtrip, no?
Can't the 303 contain the payload of that other resource along with a C-L?
"Except for responses to a HEAD request, the representation of a 303 response ought to contain a short hypertext note with a hyperlink to the same URI reference provided in the Location header field."
just an 'ought to' :)
Why not simply "200" with C-L?
So does C-L point at the same query results at this point in time, or does it point at a resource that gives updated results for this query?
Ironically, I had a draft addressing this question (https://greenbytes.de/tech/webdav/draft-reschke-http-get-location-latest.html) and was told it wasn't needed because there's C-L.
I don't think the GET-ability of the URI in C-L is the most important aspect here, it's that it provides a key for which to cache the result. For repeated requests (refreshes), the client should of course GET the URI of C-L in order to benefit from the built-in cache mechanisms of GET.
The status code of the response from a QUERY request may be up to the server to decide and is perhaps not something this spec should say anything about?
The definition of a "safe" method is that the client does not request or expect changes to server state, though the server might of course perform state-changing actions on its own initiative. In that light, 201 seems a very strange response. The client did not ask the server to create anything.
The use-case that I envision is using this for a refresh with fewer bytes on subsequent requests. Is there a real-world argument for needing to fetch a historical snapshot of a query that wouldn't be served by simply including a timestamp on a fresh query (and then potentially getting a URL to redo that query in the future)?
I agree a 201 response from a safe method request is weird, @MikeBishop. But it's no more or less weird for QUERY than for GET. If anything should be said about this, I think it belongs in section 4.2.1 of the HTTP specification which may cover this well enough already:
This definition of safe methods does not prevent an implementation from including behavior that is potentially harmful, that is not entirely read-only, or that causes side effects while invoking a safe method. What is important, however, is that the client did not request that additional behavior and cannot be held accountable for it.
So 201 is permitted, but is admittedly not something the client can request and therefore possibly not even expect. I think 303 is a better fit, personally.
I don't think either of the Location or Content-Location headers can be used to approriately convey "this is an alternative URL at which you can perform a GET request to repeat this query" - except perhaps a permanent redirect.
Consider for example the QUERY equivalent of Google's I'm Feeling Lucky button
I feel like one interesting aspect of this is that returning a Location or Content-Location header does have some differing meanings. A Location might indicate that there is a resource that was found, that can now be located, and might support all sorts of representations. And a Content-Location header would indicate a permanent place to view this particular representation of the resource discovered by the QUERY. Arguably, both could make sense.
I don't think that either could/should imply that the location is an "immutable snapshot." They're simply discovery of resources.
From that standpoint, I think 201 Created only makes sense if you are in fact directing the user to an immutable snapshot of the result. Other resources discovered should already exist, the only think we could create is resource that represents this query.
I don't personally think that creating a snapshot is an oxymoron for a safe method. The resource you interacted with is not invalidated, something else is just there now too.
However, I think it would be confusing to use Location to mean two different things (200: "Here's the resource you found," 201: "Here's a permanent location for the response to this query.").
Just wanted to throw a couple thoughts into the ring :)
Not sure. It implies an additional roundtrip, no?
@reschke to avoid the extra round trip while at the same time allowing a fully-cacheable GET resource, an HTTP/2 server could send PUSH_PROMISE with the result, and then send 303 See Other with that Location.
Importantly, 303 See Other with Location still works as desired when PUSH_PROMISE is not supported or is disabled, though with an additional round trip for the subsequent GET request to the server.
@gstrauss - are you aware of https://developer.chrome.com/blog/removing-push/ ?
@gstrauss - are you aware of https://developer.chrome.com/blog/removing-push/ ?
I was not. Thanks for the pointer.
FWIW, I prefer QUERY response 200 OK with optional Content-Location. Simpler proxies can cache subsequent GET requests to the location provided. (Your decade-old draft for GET-Location would be even more explicit.)
303 See Other with Location is also valid. While it could optionally provide a body, I think that clients would generally look for Location and make a new request to that Location with 3xx instead of displaying the response body provided with the 3xx response.
For QUERY, wouldn't caching proxies need to understand creating a cache key combining both QUERY headers and QUERY request body? For privacy/security, clients might want to include request headers to ask that proxies not cache such queries.