Posted by CommonGuy 16 hours ago
"Using GET with a Body works"
Seems like this is going everyone's head. You're not supposed to use GET with a Body, this is a hack, therefore having an explicit method makes sense.
Just because it works, doesn't mean its the right way
The use case of QUERY is because POST conveys non-safe, non-idempotent requests which can potentially modify stuff according to the REST spec. GET requests on the other hand convey retrieval of a resource. However, due to GET requests not having a body, there's a limit to the amount of data you can put in the URL and you also cannot put sensitive data in it.
Additionally, GET requests are meant to be highly cacheable by default while a lot of the QUERY type requests are usually meant more for one-shot access.
QUERY is meant to address these limitations.
I think the point made is that _all_ existing web servers have no idea what a "QUERY" is anyway, so changes need to be made anyhow.
Hacky things not working is a feature, not a bug.
> Just because it works, doesn't mean its the right way
Tell that to anybody in the business long enough to decipher someone else's Perl!Why not just standardize it? It seems to be a better way than adding a new method.
2) A plain separation between GET should only accept query string parameters and QUERY should only accept body parameters potentially reduces attack surface of attackers trying to mix and match the two to find potential order of precedence attacks.
But specifying this behavior would get you in the same situation as adding a new method: everything not up to date with the spec will keep behaving poorly but newer system would work.
The only benefit of adding a new method is for marketing/awareness: it may end up getting support faster than the alternative because it sounds as a sexy new thing to implement. This kind of benefit should not be overlooked, but we should also acknowledge its limits: most of enterprise stuff (WAF, frameworks, etc.) are not going to work overnight just because it's a new method instead of a spec change.
Except it doesn't. Some API gateways outright strip request bodies from GET requests to prevent them from being forwarded.
It sounds like most people with the "just use GET" nonsense are far from having any experience in cloud computing.
So, change is required. Just change GET to allow for body and move on.
Most of the systems that are blocking GET/body could be easily tweaked to allow it. Today. As is.
QUERY will likely need firmware updates, core engine updates, etc.
Meanwhile, tweaking GET is a rule change.
"Using GET with a body isn't in the spec, WAFs and webservers that haven't been updated might reject it!"
Ok, QUERY wasn't in the spec when those were written either. What do you expect those appliances to do with a totally unknown verb?
It's a welcome addition but the new method is pure marketing. There's no reason the update couldn't have been to expand GET instead of add support for QUERY.
405 Method Not Allowed
We have existing standards for unsupported methods.
https://news.ycombinator.com/item?id=48568502 (4d ago, 173 comments)
https://news.ycombinator.com/item?id=29794838 (4y ago, 125 comments)
Will be fun when those see a whole new http verb, I bet that leads to at least DoS by the track record of that company.
Given that most websites only ever use a handful of methods (even once you account for REST APIs using PUT, PATCH and DELETE now), and that list very rarely changes, the WAF developers tend to look at this question from the opposite angle: when you know there are only half a dozen widely used methods, why would you allow anything else by default?
It should adept reject what it does not expect.
So is using QUERY requests for quite some time from now.
One should adhere to Best Practices since one cannot control every device between the app and the user. Best Practice says “GET has no body. QUERY can have a body. If QUERY fails (405), use POST with the body.” And eventually, enough proxies will behave well enough that at least the HTTP bit of the app has a chance of working.
Do you test with a proxy? I know I don't, and if I would it'd be the latest version of squid.
Some of those non-conforming middle boxes could be unattended black boxes in the back of a closet somewhere on the 3rd floor. Who knows. Some customers would consider alternatives to your offering because it doesn't work, others would file a support ticket and there becomes an incentive not to use the new and shiny. The broken middle black box vendor can't be bothered and keeps selling broken boxes. Shit like this is why we can't have nice things.
The biggest win is how intermediary boxes now have concrete guidance that a specific HTTP request is both safe, idempotent, and carries a request body. Up until now none of this existed, and at best developers could use unsafe methods to carry request bodies (see GraphQL and how it uses POST for queries)
All in all, I dislike the overall focus on the HTTP method when designing "RESTful" interfaces. If all we're building is, effectively, an RPC, why would the cacheability meta-information be the first thing we specify?
> I've had my fair share of situations where I wished for something like HTTP QUERY.
Using POST instead comes with no drawbacks
I'm not sure QUERY is a great solution, because in the context of a web application absolutely no one enjoys using a page that does not keep its state on refresh, so that really limits where QUERY makes sense, but if you have a case that is not driven by navigation, great.
Not so fast, champ. It matters nothing what your library let's you run away with. What matters is that every single box in the internet between you and the origin server will tolerate, and your pet library doesn't have a say in that.
> Using POST instead comes with no drawbacks
There's a hefty share of ignorance in your comment. Between POST being classified as an unsafe method and the absence of support for cashing, there are plenty of downsides of abusing POST for query requests.
As the RFC was initially proposed by someone from Cloudflare, were you aware that not even Cloudflare support caching POST requests? Their unofficial support for caching POST requests is to create a fake GET request to serve as cache key and use that to cache the response. This is the kind of hacks everyone is forced to go through instead of using something like QUERY
Similarly there are good arguments that if you were designing this from scratch it would make sense to still separate QUERY and POST. To some extent they mean very different things: "search" versus "create"/"do". Some of that is a modern expectation from years of mapping the common "CRUD" concepts to "REST": POST ~= Create; GET ~= Read; PUT ~= Update; DELETE == Delete. But that's a lens that's still useful in designing the thing from scratch even if it wasn't necessarily in mind when HTTP was first designed (especially given the different verbs in HTTP terminology).
- request-with-a-body
- idempotent-request-with-a-body
- safe-request-with-a-body
because the additional constraints induce properties that are extremely useful to general purpose clients ("I didn't get a reply to my idempotent-request-with-a-body, can I resend it without risking loss of property?")
Would someone then come along an introduce safe-request-without-a-body method? After all, we can already meet that "need" with safe-request-with-a-body and content-length: 0.
Think rfc-5789::PATCH - mechanically, it's just another request-with-a-body, but with more tightly constrained semantics. But general purpose components can take advantage of the additional properties, and so we introduce a "niche" method with tighter constraints.
Document resource manipulation is a common case, so we probably end up with a family of specialized methods, in much the same way that we have a bunch of WebDAV methods.
1. What the most popular HTTP servers actually accept
2. What the most popular HTTP clients actually send
3. What the RFC "standard" says
Personally I choose #1. I don't use the most popular HTTP clients
For example, under definition #1, I can do HTTP/1.1 pipelining with POST
The RFC "standard" often comes after the software implementation(s); most RFCs document what's already in use on the internet. As the selection of software expands, some competent software authors trying their best still often struggle to conform to RFCs. Go figure
To me, the source code of the most popular servers in use is the standard
Unless you're really going to improve things or the existing practices are really too painful, standards should follow convention. Even though GET+body is not handled the same everywhere, it's easier to make that the standard than it is to make a new syntax the standard.
Is there some research or study that you base this claim on? What is the reasoning? Can you elaborate?
Likewise creating a new syntax for something that already exists means you are just adding to the heap of stuff that needs support on mainstream servers, and as I already said it will probably create compatibility issues as the old deprecated/illegal syntax is removed. This is unnecessary friction.
And really what is the advantage of a new syntax? That needs explaining.