- why not just extend GET to make a payload not "undefined" anymore? Instead now people have to wonder whether to use GET or QUERY. The non-idempotent methods have at least a difference in semantics, while this here seems mostly another way to provide parameters for essentially the same action.
- QUERY is a somewhat bad name choice, given that URL parameters are also refered to as query string
I think this was a situation where either choice (extend GET, create QUERY) was less then ideal but at least if you create a new namespace in QUERY you can avoid arcane business logic around GET by various caches, loadbalancers, proxies, and other software that made who knows what terrible assumptions around GET payload shape.
> you can avoid arcane business logic around GET by various caches, loadbalancers, proxies, and other software that made who knows what terrible assumptions around GET payload shape.
I wish standards bodies weren't afraid of angering the feet-dragging vendors who haven't had to update their shitty middleboxes in 20 years despite charging their customers through the nose for them. Maybe it would be better for a healthier web if these dinosaur machines got broken once in a while.
There is enormous spend and investment that occurs under low volatility assumptions. People don't want their gear to break for features they may not want or need (see: IPv6 uptake, Python 2->3 migration timelines if at all, etc). Standards bodies exist to serve users, not the other way around. Balance backwards compatibility with forward velocity.
It's all fun and games until it turns out your home ISP is one of those dinosaur machines and now you can't log onto HN because none of the routers you can connect to understand GET with a body.
> - QUERY is a somewhat bad name choice, given that URL parameters are also refered to as query string
Slightly confusing, I agree. But given that neither are called just "query", and HTTP methods being usually in all caps, I think it won't be as bad. "Query component" (from URIs as specced) VS "QUERY method" should be clear enough.
I wondered the same thing. Perhaps it is easier to roll out a new request method, rather than increase the scope of an existing request method. For example, a lot of extant middleware might silently drop a GET requests body, whereas they would just error out upon seeing "QUERY ..."
And it is often easier to argue that software should add support for a new method than that it should change semantics that other users/customers may depend on even if those semantics aren't ideal.
> QUERY is a somewhat bad name choice, given that URL parameters are also refered to as query string
SEARCH and REPORT, which are probably better names, were already taken by WebDAV, a pre-REST style protocol layered over HTTP that loved (loves?) registering new HTTP methods.
either extension method seems a lost cause, given that most browsers/web servers don't fully support the 7 existing http verbs, even with decades to do so.
Oh, I did not know about that! You learn something new every day at HN :) Thanks!
Granted, I guess you could argue that because you can use whatever method you want in practice, there is a unlimited set of methods available (depending on how long string whatever server you're using could create, if they are parsing it and so on)
yah, i should have specified 'common' or 'web', or something like that. i had a feeling someone would raise a more technically precise but also more esoteric rebuttal.
The spec doesn't say how browsers should represent such request in the browser address bar. The nice thing with GET is that you can copy a search url, bookmark it or share it with someone, and they get back the exact same results. How would that work with a QUERY method?
In HTTP, clients are user agents and a web browser is only one kind of user agent that is specialized in fetching and displaying web pages. Like PUT and DELETE, this is clearly meant for APIs, not web pages. (Although sufficiently "advanced" web pages may make API calls.)
It's more for the SPA age of web apps, where we want to GET a resource from an API, but have a body in the request. For example fetching the user who is currently logged in and getting a JSON response back; it's not something you would do in the address bar.
I'm not sure it makes sense for an HTTP protocol method standard to describe how browsers should allow it's input in the URL bar - two very different standards realms.
That said you should be able to trigger any custom HTTP request your browser support via pasting/bookmarking a `data:` or `javascript:` construction if you really want. As of now the URL bar is GET only when you enter a URL.
> I'm not sure it makes sense for an HTTP protocol standards to describe how browsers should allow it's input in the URL bar - two very different standards realms.
Just as a small remark, HTTP protocol standards do - or have at least - considered URL input so far in a wider, client-side meaning. Some details are left for the clients, e.g. it differs across browsers how certain URL characters are interpreted when entered into the URL bar (or on the command-line, e.g. with curl(1)).
Apart from that, HTTP URLs are part of the same HTTP standard, aren't they?
HTTP URLs and HTTP methods are two very different things, somewhat conflated in that the browser treats URLs in the URL bar as a shorthand for generating a GET. While URL encodings are well standardized for general use in RFCs the parsing into an HTTP GET when entered into the URL bar is not, it's just good UI. The same would be said about the QUERY method standard, it's not about describing how the browser UI should allow making such a request header just what a valid one is.
Similarly to as if you were using POST requests I'd say. So if you want the users to be able to navigate to a URL and get the same results for a POST request, you'd make the client-side read URL parameters and sculpt the POST request and send it.
This is great. Note it is co-authored by James Snell who I know from Node.js core. He has been a very prolific member working on things like QUIC in Node and web APIs.
I can definitely see why this could benefit his work (at Cloudflare) a lot since it would enable caching of results currently done through POST queries.
I've seen this done a few times and in most of those cases I agreed it made sense. I've thought about this myself a few times too.
But it does lead to unexpected behavior. Users are trained to copy/paste links and send them. If the body only included stuff like auth tokens then it would be ok, but if relevant query stuff was in there (like page size, for example) that would lead to different results that would ultimately be deleterious IMHO.
The copy/paste URL use case is a fair consideration. The places where I’ve seen request bodies on GET requests are APIs [2] that are not seen by the end user.
> The non-normative examples in this section make use of a simple, hypothetical plain-text based query syntax based on SQL with results returned as comma-separated values. This is done for illustration purposes only. Implementations are free to use any format they wish
I guess that they purposefully did not use JSON or any other widely used format to avoid giving the appearance that that format is required or encouraged.
As for copying/sharing links, I think that was covered in another discussion above: Just like with POST, it's likely just not intended to do QUERY requests via links or through the URL bar.
> This specification defines the HTTP QUERY request method as a means of making a safe, idempotent request that contains content.
I’m already seeing implementors failing at following the spec here – they will equate the QUERY method to querying a mutable database, which won’t give reproducible results, and to give reproducible results the server would need to save it. Now to make it idempotent, will be an ad-hoc decision of each server. It seems contradictory. At this point it’s indistinguishable from a PUT on a resource that represents the query itself.
"Idempotent" does not mean successive identical requests must return identical content. For example, two successive GET requests to the same URL will not return identical content if in between them the owner of the website changes the page at that URL. Similarly, if the source of the request content is a mutable database, two successive QUERY requests with the same request content will not return identical content if the database is mutated in between by someone else.
All "idempotent" actually means is that successive identical requests must induce the same change in the server's state due to the request itself. In the case of verbs like GET and QUERY, that is trivially true since they induce no change in the server's state at all. But the content of the response can of course change due to other events happening on the server. If "idempotent" required that not to happen, no request could ever be guaranteed to be idempotent.
I mean: I don't see the point to have a new method that still gives the same (weak and misnamed) idempotency guarantees of GET. We already have GET, and a new method isn't necessary just to pass request data.
I would rather have a method that _may_ have side-effect on the server-side, but it's actually idempotent from the client-side (as in, truly reproducible results). That already exists in the form of a PUT + some content addressing scheme, for example, but it's open to each implementation.
If visit counters are considered to be changes in the server state, then servers that implement them are violating the requirement that GET requests must be idempotent.
> I’m already seeing implementors failing at following the spec here – they will equate the QUERY method to querying a mutable database, which won’t give reproducible results,
Safe requests (all of which are necessarily also idempotent) are not reliably reproducible; GET of the same resource changes if there are server-state changes induced by other requests between GETs.
So, what you suggest is not failing to follow the spec.
Yeah it's already created confusion for me. I read it as essentially a side effect free request with a request body. Not that the data behind it was necessarily immutable but that the query didn't do any mutations.
We should just create a revision for RFC 2616 to extend the GET method to allow request bodies. Most HTTP frameworks already support this behaviour anyway.
RFC 2616 has already been obsoleted, and there is a draft (I think on its 19th draft or more) RFC obsoleting the set that obsoleted RFC 2616.
> to extend the GET method to allow request bodies.
Adding a new method is safer than changing the semantics of an existing one, “has a body” is a pretty major distinction for an HTTP message, whether a request method or response status.
After spending pages telling the reader that the query should not affect the server's state, the only example given appears to do exactly that: initiate a query and return a GET url to retrieve the results.
Either the GET request actually triggers the database request, which makes the QUERY request totally redundant, or the QUERY request relays a call to a database interpreter and the server responds with a location to retrieve the results.
Second, how would the http server know that the query is both idempotent and safe? Providing an example with SQL-like code makes it look even more like a bad joke...
I see this creates (at least) two problems and solves none. Do the authors know which problem they hope to solve?
If I had more time I'd look into their bios. Something tells me this is a typical case of "I put my name in a RFC", unless they work under the umbrella of some GAFAM who needs a new HTPP verb without disclosing why.
Is it really OK to add a new method to HTTP 1.1? I think would be quite an unfortunate decision, because it would make the version numbers absolutely meaningless if all of a sudden new methods can pop up without them changing.
"The list of methods allowed by a resource can be specified in an Allow header field (section 14.7). The return code of the response always notifies the client whether a method is currently allowed on a resource, since the set of allowed methods can change dynamically. An origin server SHOULD return the status code 405 (Method Not Allowed) if the method is known by the origin server but not allowed for the requested resource, and 501 (Not Implemented) if the method is unrecognized or not implemented by the origin server. The methods GET and HEAD MUST be supported by all general-purpose servers. All other methods are OPTIONAL."
The short version is that it's perfectly fine. This doesn't modify the HTTP spec, and it uses established extension mechanisms.
The long version:
RFC 7231 defines the standard HTTP methods in section 4.1. [1] Looking at it, the only methods that are required are GET and HEAD. All others are optional, and the spec explicitly calls out that additional methods may be created and registered with the IANA.
Looking closely at this RFC reveals two things:
1. It doesn't modify any of the HTTP RFCs. (There's no "Obsoletes" or "Updates" header.)
2. In section 6 of the QUERY RFC, it requests that the IANA add the new method to its registry. That follows the guidelines in RFC 7231 section 4.1.
I did not know about Ruby Python back then... now I feel it's too late... eventually I'll try and change the name to binarytask since I bought binarytask.com...
Any reasonable system requires offset.
Also, it would be nice to have a search id that allows client to fetch further records in a linear way without risking data shifts when new records get added. The last "must have" would be to have some form of ordering.
Am I right in thinking that this is basically an alternative to URI query parameters? Presumably to make parsing the query and caching the results easier.
I think the biggest motivation I've seen every time GET bodies are brought up is the size limit on request bodies is normally much larger than on URIs and especially query builder type interfaces run up against this, which is why e.g. elasticsearch does this.