Top
Best
New

Posted by CommonGuy 16 hours ago

The new HTTP QUERY method explained(kreya.app)
208 points | 159 comments
ramon156 13 hours ago|
"QUERY is just GET"

"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

EnnEmmEss 12 hours ago||
Using GET with a Body doesn't work if you try using it in the browser with JS fetch for example[1]. Additionally, a lot of existing web servers by default ignore GET requests with a body.

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.

[1]: https://github.com/whatwg/fetch/issues/551

krackers 2 hours ago|||
>Additionally, a lot of existing web servers by default ignore GET requests with a body.

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.

nesarkvechnep 9 hours ago|||
There's no such thing as REST spec. The closes mechanism to actual REST is to create a resource using POST and then query it using GET. You have the added benefit of the resource being cacheable.
darig 7 hours ago||
[dead]
jefc1111 11 hours ago|||
Yep. We had to change our app when we took on a client with a strictly configured WAF which rejected GET with body. I know I have come across multiple points where I have used POST when I know it is wrong, or GET with a body, when I know it is wrong. So I welcome QUERY!
entuno 9 hours ago||
AWS CloudFront blocks GET requests with a body, so it doesn't even have to be a particularly strict setup or an explicit WAF.
ronbenton 12 hours ago|||
I’ve seen a framework strip body content off GET requests, so doing hacky things doesn’t even always work. The QUERY method is a welcome addition
pdpi 12 hours ago|||
Insofar as I'm concerned, a GET request with a body is an attack-shaped aberration. E.g. Somebody who's trying to get me to mix up validating query string parameters and request body parameters.

Hacky things not working is a feature, not a bug.

tgv 12 hours ago||||
I'd say it's the framework doing the hacky thing. It should be optional. AFAIK, the HTTP spec allows for it, under certain conditions. "A client SHOULD NOT generate content in a GET request unless it is made directly to an origin server that has previously indicated, in or out of band, that such a request has a purpose and will be adequately supported."
psychoslave 12 hours ago|||
Is the stripper service in question already implementing it?
Bombthecat 11 hours ago|||
Some security/ API gateway block requests when it's a GET with a body.
somekindaguy 4 hours ago|||
Why not just add an optional body to the spec for GET
dotancohen 13 hours ago|||

  > 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!
nixon_why69 10 hours ago||
It's possible that the slogan "There's one obvious way to do it" as a riposte to "There's more than one way to do it" was more responsible for Python's first wave of success than anything else.
maxloh 10 hours ago|||
It sounds like GET with a body is just undefined behavior.

Why not just standardize it? It seems to be a better way than adding a new method.

WorldMaker 4 hours ago|||
1) Changes to how GET works likely require a new HTTP version to assure maximum breaking change awareness. We're already in a Postel's Law state where we have HTTP/1.1, HTTP/2, and HTTP/3 all running side-by-side for reasons that all three are very different under the hood at even the transport layers. Do we really want to add HTTP/1.2, HTTP/2.1, and HTTP/3.1 to that list? An entirely new method is easier to apply horizontally to all three versions, because the HTTP standard already allows that as an extension mechanism. (There's an IANA registry for HTTP methods and HTTP methods such as WebDAV's have always been their own standards outside of HTTP RFCs.)

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.

Vosporos 8 hours ago|||
A lot of un-updateable software out there that strip the body. Especially when the companies behind it doesn't provide support anymore.
earthdeity 8 hours ago||
will those support QUERY?
cryo32 12 hours ago|||
The whole stack is a pile of badly designed hacks. Not much point in fixing it now. I mean they can’t even spell referrer correctly.
stymaar 10 hours ago|||
You're missing the point. Using GET with a body is currently unspecified, so of course you're not supposed to do it (though you're not forbidden to either).

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.

locknitpicker 11 hours ago|||
> "Using GET with a Body works"

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.

topham 10 hours ago||
QUERY won't be supported by them either.

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.

akersten 8 hours ago|||
Yeah I really don't understand the anti-GET-body argument.

"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.

WorldMaker 4 hours ago||
> What do you expect those appliances to do with a totally unknown verb?

405 Method Not Allowed

We have existing standards for unsupported methods.

WorldMaker 4 hours ago|||
Sure but 405 Method Not Allowed is a response you can fallback from, whereas "body was silently stripped by a middlebox" is not as easy to know when it happens, much less deal with.
bellowsgulch 8 hours ago||
So a POST with explicit caching semantics?
em-bee 7 hours ago||
no, a POST that is idempotent. caching is an optional side benefit.
ktpsns 15 hours ago||
HTTP QUERY was discussed many times in the past here:

https://news.ycombinator.com/item?id=48568502 (4d ago, 173 comments)

https://news.ycombinator.com/item?id=29794838 (4y ago, 125 comments)

TheLudd 10 hours ago|
Yes but the author wants to promote his postman replacement
Asmod4n 12 hours ago||
Slightly off topic Funfact: you can buy a several thousand dollars expensive ssl intercepting proxy appliance which doesn’t support anything beyond http/1.1.

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.

nness 10 hours ago||
What is the use-case for a WAF/proxy/etc. to block unknown HTTP verbs? It feels like a pathway for obsolescence with no actual security benefit?
entuno 9 hours ago|||
Historically there have been vulnerabilities in various applications due to HTTP method tampering, and in the days of people accidentally leaving WebDAV enabled then methods like PUT and DELETE could be very damaging. Plus the issues with TRACK and TRACE.

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?

Asmod4n 10 hours ago|||
Not block, straight out crash the process is my guess will happen here.
topham 4 hours ago||
If it crashes it's a security issue.

It should adept reject what it does not expect.

Stitch4223 12 hours ago||
Not mentioning the vendor… means your comment is true for every vendor :)
Asmod4n 12 hours ago||
That would be lancom. Good routers, the rest not so much.
tosti 14 hours ago||
> using HTTP GET with a request body is a bad idea, as for example users behind a corporate firewall or a different browser may be unable to use your website.

So is using QUERY requests for quite some time from now.

jy14898 13 hours ago||
405 Method Not Allowed is trivial to fall back to POST. How do you know the GET request behaved incorrectly?
tosti 13 hours ago||
That's assuming the corporate proxy is well-behaved.
jagged-chisel 12 hours ago||
Then all bets are off, and I guess we just can’t HTTP ever again because a proxy can misbehave.

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.

tosti 2 hours ago||
We can HTTP and all bets are still off, probably.

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.

jbverschoor 14 hours ago|||
Yeah, query seems just GET with a body. No difference in protocol nor behavior
gl-prod 13 hours ago|||
The difference is the method. Query you're saying I can use body. GET you should never use body.
locknitpicker 10 hours ago||
> The difference is the method. Query you're saying I can use body. GET you should never use body.

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)

_flux 12 hours ago||||
There is the Accept-Query header https://www.rfc-editor.org/info/rfc10008/#appendix-A.3 that tells you can use QUERY. That's a bit different.
ComodoHacker 13 hours ago|||
Except compatibility. If you're using classic GET and it's enough for you, you aren't affected.
4gotunameagain 13 hours ago||
What is compatible with a QUERY but not with a GET ?
dotancohen 13 hours ago||
Intermediate proxies, caches, CDNs, firewalls, and load balancers.
4gotunameagain 10 hours ago||
That is only in the case of GET with a body though.
dotancohen 9 hours ago||
Yes. That is the issue under discussion, e.g. not "classic GET".
flanked-evergl 9 hours ago||
The fact that some infrastructure is poorly maintained is not a reason against evolving protocols, it's a reason to maintain infrastructure better. It's really not that difficult to do.
waweic 13 hours ago||
I wonder what the drawbacks of standardizing a GET body would have been. CoAP already has it (which creates friction in building CoAP<->HTTP proxies).

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?

braiamp 12 hours ago|
A absolute swats of middle boxes that will not get addressed ever. As industry, it's preferable to create something that is a hard break and makes players upgrade and give people a feature to argue for said upgrade
8-prime 14 hours ago||
It's interesting to see additions to HTTP methods as it much feels like the existing ones are set in stone. At least for the time that I have been a developer. I'm curious to see how fast the adoption/support for HTTP QUERY will be. I've had my fair share of situations where I wished for something like HTTP QUERY.
wseqyrku 8 hours ago||
This is why there's another method. It's easier to communicate 'QUERY method support' rather than get-with-a-body-no-not-the-one-that-is-unspecified-it-is-accepted-with-slightly-different-semantics-now-EOF.
PunchyHamster 14 hours ago|||
zero. Many libs will/can just request method as a string so you can start coding now

> I've had my fair share of situations where I wished for something like HTTP QUERY.

Using POST instead comes with no drawbacks

rezonant 13 hours ago|||
I think the article summarizes pretty well what the drawbacks of POST are: unclear idempotency (well it's actually pretty damned clear: they are not cacheable). That complicates caching logic, and that's not just for the application server itself, but any reverse proxies in front of it as well as the user agent itself.

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.

victorbjorklund 10 hours ago||||
Much harder to get CDN:s/proxies/etc to cache a post request vs this new one (assuming it’s actually becomes used)
locknitpicker 10 hours ago|||
> zero. Many libs will/can just request method as a string so you can start coding now

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

hparadiz 14 hours ago||
I can implement it in about 10 minutes. Not even kidding.
echoangle 13 hours ago||
In what role? As a user writing client code or when implementing the caching middleware or the Webserver?
hparadiz 13 hours ago||
In my CRUD controller that I already have.
8-prime 9 hours ago||
This assumes that all of the infrastructure surrounding your application also plays nicely with it and supports it, as stated in the article. That's why I expressed my interest in speed of adoption in the first place.
mi_lk 12 hours ago||
OK, but stop trying to make fetch happen.
doginasuit 11 hours ago||
Would this be a defensible decision if the spec were designed today, an additional read method that takes the same argument, entirely for the purpose of not ignoring a specific property? It seems like just the path of least resistance considering all the controversy and legacy tools. That is not a good way to maintain the functionality and long-term relevance of a spec. But if there is a good reason to design it this way from the beginning, I'm curious to know more.
WorldMaker 3 hours ago||
There are good arguments that if you were designing this from scratch it would still make sense to separate GET and QUERY. GET are things addressable purely by URI. QUERY are things that need HTML forms or JS to initiate (but optionally may return GET addressable URLs for future requests).

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).

voiceofunreason 9 hours ago||
My guess is that if you were building all of this from scratch, you would start with

- 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.

1vuio0pswjnm7 7 hours ago||
Three different definitions of the hypertext transfer protocol (HTTP). Choose one

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

veltas 10 hours ago|
The other issue with adding a separate supported way to do what people did with GET+body is that we will probably see servers slowly drop support for the GET+body approach when QUERY gets widespread support/usage, and then a ton of other stuff will break.

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.

flanked-evergl 9 hours ago|
> 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?

veltas 4 hours ago||
With standards it helps to reconcile existing behaviour, rather than create new unproven syntax.

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.

flanked-evergl 22 minutes ago||
But it's not existing behaviour. It does not already exist. Breaking the semantics of something that exists means that things will work inconsistently. Breaking the semantics of get will also create compatibility issues.
More comments...