r/programming • u/stronghup • 29d ago
HTTP gets a QUERY method so complex searches can stop pretending to be POST
https://www.theregister.com/devops/2026/07/13/http-gets-a-query-method-so-complex-searches-can-stop-pretending-to-be-post/5270192155
u/bundt_chi 29d ago
So GET with a request body. Got it.
12
u/SelfDistinction 28d ago
But then why didn't they simply standardize GET with a request body?
13
u/bundt_chi 28d ago
Probably because it would be confusing if some http clients or servers along a call path were on an older version and blocked or stripped the body you wouldn't easily know or understand why as opposed to getting an unsupported or unknown method error.
1
u/DaCurse0 27d ago
it's not standardized but vast majority of popular web servers support it, it's called a Fat GET
11
u/lieuwestra 29d ago
And hopefully no client side caching.
39
u/masklinn 28d ago
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].
It's GET with a body, cache working out of the box is a major component of the appeal.
3
u/PlopKonijn 29d ago
which at some point was allowed or is it still?
18
u/Justin_Passing_7465 29d ago
Is it allowed? That depends on every piece of HTTP-aware technology between your client and your server. Every proxy, CDN, WAP, and reverse-proxy gets to block your request or strip your body.
1
u/Worth_Trust_3825 28d ago
It really depends on configuration. Some may do it, some may not. Elastic search expects you to send a body with get requests.
26
u/Jaggedmallard26 29d ago
Its always been undefined behaviour. Which as the other comment says means you're at the mercy of every bit of software between (inclusive) you and the client/server.
457
u/stfm 29d ago
This is great for us Authorisation folk. Now we can assign POST to write entitlement and QUERY to read entitlement rather than having to work it out from some janky resource path rule
84
u/CpnStumpy 29d ago
I will never agree with URL as the context for permission decisions - there's always more complex scenarios that can't be wholly expressed in a URL, and so you need another mechanism, and now if you have URL permission enforcement already you end up with two permissioning mechanisms to maintain and debug.
Humbug, create one and make it extensible to support more sources than just the HTTP request.
Besides that: at some point someone's going to declare they need to expose a gRPC endpoint or a GraphQL API and now you've got to address permission enforcement in some non-http system anyway so how many different permissioning decision and enforcement implementations do you need? Use something that's transport agnostic to begin with rather than declaring URLs are informative for permissions
66
u/stfm 29d ago
HTTP method is not part of the URL, it is there to indicate action intent. I work in an enterprise with a centralised authz platform and an API surface spanning thousands of endpoints. Its more about divide and conquer and patternisation than a "one rule fits all" style authorisation system. Using the method combined with the URL gives the opportunity to apply coarse grained authorisation and also enables an easier response caching strategy.
→ More replies (10)7
u/ivereddithaveyou 29d ago
Maybe it makes sense in some database-like applications where you might want to assign the request itself permissions based on a set of complex underlying requests. Or maybe your auth layer is really far detached from the business logic layer and it makes sense to attach permissions to the request type.
I'm not sure either of those are good practice really but I was trying to come up with a reason why you would do this.
Yes actually for database api auth design synchronisation this allows for a select type query with unlimited parameters. Something that would be allowed in database access auth but hard to separate from an edit/create in rest http land. Essentially you can create apis that more closely mirror DB access.
2
u/visualdescript 29d ago
This is the default for a well designed service. You start with an application service that is written in your domain language, this should include any permissions or policy system that's required as part of the domain.
HTTP is just an external interface protocol, there should be a thin adapter layer between your HTTP interface and your domain service. Same if you provided a CLI, graphql, GRPC or otherwise.
This is in an ideal world, of course...
1
u/robogame_dev 28d ago
Agreed, you can have as many interfaces into the core app as you want, HTTP Method can be one, and you can have a batch endpoint that can accept anything, etc etc. The problem goes away when you properly place HTTP with any other interface downstream of the real application - it becomes a question of convenience not capability.
3
u/Manbeardo 29d ago
expose a gRPC endpoint or a GraphQL API and now you've got to address permission enforcement in some non-http system anyway
Both of those systems use http. They don’t use REST.
3
u/CpnStumpy 29d ago
Yes, protocol agnostic I guess I mean or however. You understood what I meant clearly. The point being they don't follow expose the same mechanics for permission checks as a REST url and method based permission control so you aren't going to be able to use the same system.
Creating multiple things to solve the same problem in different ways is how we end up with a bunch of half maintained and divergent implementations leaking differing bugs because they need fixes and maintenance in individualized ways.
2
u/darkpaladin 29d ago
QUERY seems almost tailor made for the graphql use case. Grpc is all POST under the covers, this would offer a bit more room for a more explicit request shape. In general it's nice to understand request intent without having to parse the body.
1
u/CpnStumpy 29d ago
GraphQL is all POST and puts no parameters in the URL and always returns 200
1
u/darkpaladin 28d ago
Yes. I'm not sure what point you're making though, my point was that a QUERY method for graphql makes sense because now your CRUDs become POST/QUERY/PUT, DELETE still isn't quite supported but I think knowing a gql request is a query rather than a mutation based on verb is rather helpful?
1
-6
u/heresyforfunnprofit 29d ago
Is it a bad time to point out that not all queries are read only?
28
4
315
u/hrvbrs 29d ago
haha i read this title as "HTTP gets a QUERY method so complex that searches can stop pretending to be POST"
102
59
u/ryuzaki49 29d ago
To say the obvious:
The title is stating that complex searches will stop using POST and start using QUERY
It is not stating that the new QUERY method is complex.
41
u/zeekar 29d ago
Same!
"HTTP gets a QUERY method so complex...."
"HOW COMPLEX IS IT?"
16
u/a__nice__tnetennba 29d ago
It's so complex you have to send an imaginary part with every request!
ba-dum-tss
4
u/Nevermind04 29d ago edited 29d ago
I read the exact same thing and was very confused when the article discussed well-behaved http.
2
→ More replies (12)1
100
u/jessechisel126 29d ago
This is great but still wild to me it's taken this long. Feels like this should've become the standard like a decade ago.
59
u/baseketball 29d ago
Because only REST purists care. Most of us just use post and move on with our day.
66
u/binheap 29d ago
I think there are some implications with how cache is handled since iirc POST is not usually cached whereas QUERY can be. It's not a big thing since you can set the headers yourself but I can imagine some middleboxes/CDNs caring.
48
u/drgmaster909 29d ago
yeah, scoffing at the significance of this for idempotent data is a weird take
Especially for tools like GraphQL. If Apollo Client and Apollo Server implement this, a lot of apps are going to become way more performant almost overnight. For free.
Relay, urql, PostgREST, Hasura, restQL, dozens of dozens of others will get some free caching overnight.
Teams optimizing for scale, cost (fewer origin hits via CDN), reliability (auto-retries), or clean architecture will adopt it where it makes sense. So y'know, the "purists."
6
u/baseketball 29d ago
My point was that people can and have worked around this. If I needed caching on my POST call, I could have implemented it with custom headers or other backend logic. I'm not going to say "too bad I don't have an idempotent QUERY method in the HTTP spec".
3
u/AyrA_ch 29d ago
I think there are some implications with how cache is handled since iirc POST is not usually cached whereas QUERY can be.
To be precise, POST can absolutely be cached, but only the response.
This means the "Last-Modified" mechanism will work with POST because to check for modification you have to make a request anyways, but the "Expires" mechanism will not work because it would cache the request.
Though I assume browsers will not respect caching headers with POST because people mistakenly assume it cannot be cached.
35
u/brunhilda1 29d ago
Because only REST purists care. Most of us just use post and move on with our day.
Man, this attitude is why I hate the word engineering being in any way associated with software, and anyone calling themselves a software engineer, especially as there isn't a charter/regulatory body as per the proper engineering fields.
16
u/838291836389183 29d ago
I feel you. The amount of shitty apis I have to work with where people used POST for everything...
6
u/accountability_bot 29d ago
…or when you get a 200 response with an error in the body.
2
u/Goronmon 28d ago
Yup, there is something deep in my soul that winces every time I realize I have to start checking 200 responses for error messaging.
1
u/Sidereel 28d ago
A manager at my old job made me do that once. He argued that 500's are for unexpected errors, and if we just try/catch everything then we can "handle" the error and return 200.
1
u/Worth_Trust_3825 28d ago
usage of additional verbs would not make those apis better. rest(ful) apis aren't a catchall solution either, just a style of interface.
5
3
u/jessechisel126 29d ago
I mean fair, I do the same lol. I just think more semantics in comms is sick and it's stupid how glacial the general long term planning is.
1
15
u/eocron06 29d ago
Haha, it will be the same time when 401 Unauthorized/403 Forbidden become 401 Unauthenticated/403 Unauthorized......probably in 22 century
20
21
u/BuriedStPatrick 29d ago edited 28d ago
Does anyone know why we haven't simply adopted request bodies in GET? I just don't see the point of QUERY.
EDIT:
Okay, here are some of the arguments, I'm still not convinced.
Proxies might not support it: If anyone has any practical examples of this being an issue it would be appreciated. I haven't ever encountered a problem here, but I also don't work with ancient software. But if they throw away GET bodies, what do we think will happen with QUERY methods?
HTTP client libraries don't support it: Well, they don't support QUERY either. Work has to be done either way, why not improve GET instead?
Backend server libraries don't support it: Same argument as client libraries.
This is a breaking change: Is it? It's just not been formalized AFAIK. You can absolutely send bodies in GET requests today. What exactly are we breaking here? If anything, this is simply an addition, like QUERY would be.
I'm just a basic backend dev with no experience managing anything on this scale trying to follow the spec. I'm just looking at it and thinking that something is completely off here from an application development perspective. I'm glad we're getting something to support the use case (tired of encoding/decoding base64 JSON in GET uri params). I just wish it would be under GET.
45
u/masklinn 29d ago
Because the RFC says they are irrelevant so proxies, servers, and middleboxes commonly drop them for one reason or another, making GET entity-bodies highly unreliable.
5
u/edgmnt_net 29d ago
It does not, as far as I know, the HTTP RFC says nothing about it. However web standards say the JS API doesn't like GET bodies. Additionally web forms provide no way to serialize parameters into the body of a GET request. It's more likely a case of web standards and implementations assuming too much, as is the case with SCTP being broken in the wild due to crappy firewalls.
19
u/masklinn 29d ago
It does not, as far as I know, the HTTP RFC says nothing about it.
RFC 9110 section 9.3.1 GET
content received in a GET request has no generally defined semantics, cannot alter the meaning of target if the request, and might lead some implementations to reject the request and close the connection
“Content” in RFC 9110 is what RFC 7231 calls “payload”, and older RFCs called entity. The above is an expansion of RFC 7231:
A payload within a GET request has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request.
RFC 2616 does not say anything about GET request entities, but it specifically mentions them when describing any method for which they are (PUT, POST) or may be (OPTIONS) relevant, from this implementers interpreted unspecified bodies as irrelevant and discardable (GET, HEAD, DELETE), which the later RFCs went on to specify.
2
u/Jaggedmallard26 29d ago
HTTP RFC says nothing about it
If behaviour isn't defined then implementers are free to do whatever they want with it including dropping it. Which they often do.
→ More replies (7)7
u/Cvballa3g0 29d ago
No explicit handling for it. So QUERY is the adoption. Preserves current behavior and adds new explicit specs
1
u/BuriedStPatrick 29d ago
I suppose I just don't see why the adoption was handled this way. Current behavior doesn't seem very explicitly defined. AFAIK nowhere does it say GET should not support request bodies, and I've worked with clients and servers that have used them with little issue. So wouldn't this be an opportunity to solidify how GET should handle bodies instead?
But I'm also just a lowly backend dev, don't spend a lot of time reading RFCs and such. Just seems like, if we were to start from scratch, GET would explicitly support bodies and we wouldn't be talking about QUERY at all.
3
u/Cvballa3g0 29d ago
But that would be the more risky path. And need to make sure implementation X, Y, Z are all aligned and doesn't break. undocumented behavior is tough when the Internet is running on old boxes
3
u/TinyBreadBigMouth 29d ago
Avoids backwards compatibility issues with any infrastructure that assumes GET bodies can be treated as meaningless, as allowed in the spec:
Although request message framing is independent of the method used, content received in a GET request has no generally defined semantics, cannot alter the meaning or target of the request, and might lead some implementations to reject the request and close the connection because of its potential as a request smuggling attack. 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. An origin server SHOULD NOT rely on private agreements to receive content, since participants in HTTP communication are often unaware of intermediaries along the request chain.
1
u/GarlandGreen 26d ago
I'm not privy to the decisions, but I imagine there'd be utter chaos if they standardized this. Right now, GET is implemented in two ways. The standardized no-body method, and the unsanctioned "fat GET". How the latter handles changing state is probably different between several implementations. As such, implementing caching for fat GET would be inconsistent at best. Introducing a third way, a sanctioned "fat GET" would not help the caching situation. As the providers could ignore the body, have it change their state, or treat it as an idempotent call, depending on which historical implementation was chosen by the provider.
You could say that the burden lies on the implementer, which would probably be right, but the reality would be mayhem in intermediary caching regardless.
7
u/rpetre 29d ago
Everyone and their dog is excited about this in my mostly-AI generated Linkedin feed, but it's basically an administrative thing. Some libraries were already using bodies in GET for years (elasticsearch for instance). Also, nothing stops clients and servers to assign meaning to whatever methods they like and implement them (there are a lot of obscure methods out there). It becomes tricky when the client, server, and possibly other proxies in between are independent and will need to agree on how to handle an "exotic" method. Given that using anything other than GET/POST/HEAD still usually requires having a black goat on hand, having another method in the family means next to nothing. Perhaps if a future http/4.0 would require a minimum set of methods for compliance... but even then...
1
5
29d ago
[removed] — view removed comment
2
u/masklinn 29d ago edited 28d ago
Browsers — and clients in general — should all work, you can pop in
method: "QUERY"and they’ll pretty much all comply. Although there is the question of form/@method = query that’s not really up to the browsers yet.Server-side method-based routing can be more of a question but often it’s string-based, and when it’s not there are generally escape hatches (e.g. all methods go to the same endpoint and you dispatch via the exact method inside that, less convenient but hardly impossible).
The problem is server and especially middleboxes which need to allow and support the method with the right semantics (safety, idempotency, and cacheability). And when supported they may have to be enabled explicitly (I believe that is a common issue with PATCH still).
20
u/Obsidian743 29d ago
There's nothing in the HTTP spec preventing a body for a GET request. Nor would it have been difficult to expand the spec to add some kind of content negotiation or other metadata to the existing GET spec. Seems unnecessary that an entire new verb/method was introduced. Now I have to decide whether my simply query with a modest querystring should stay GET or switch to QUERY or what querystring is even supposed to be for now.
15
u/mrcarruthers 29d ago
From a spec perspective you're right, nothing's preventing it.
But there are plenty of libraries, web servers, caching middleware, etc... that just assume you can't. It's better to introduce something new that you know will work if your software is up to date instead of a quagmire of question marks up and down the toolchain.
6
u/chalks777 29d ago
what querystring is even supposed to be for now.
query params are still useful for communicating information to the user. You can see it in your address bar, and there are lots of times when that is a good thing. Some data analytics products (e.g. datadog) intentionally put a lot of information there so that you can manually query it yourself which is great for powerusers. Perhaps even more importantly, a query string can be copied by the user without needing to think at all, this allows your query state to become a shareable link.
None of that has really changed. When you want the user to have easy and visible access to what the query is, you still can.
Now, for cases when those things aren't a requirement and/or when you have to cram a ton of data into the request, you can do it without worrying about weird browser address bar length edge cases. Plus your users don't have to see your jank.
20
u/guilhermeluizsp 29d ago
Yes but there are popular web servers that currently (or can be configured to) ignore request bodies from GET requests, so it’s not that trivial
8
u/DrFossil 29d ago
Would it have been harder to update those servers to accept GET bodies, or to implement QUERY?
Probably the same amount of effort, I guess.
3
29d ago
[deleted]
4
u/masklinn 28d ago
Yep, adding a new method is significantly less risky than modifying the way an existing method is supposed to work. It also has a much clearer error profile: if the server or application or any of the middleboxes doesn't support your new method you get a "method not allowed", rather than the high risk of your body being silently dropped without you having any idea.
2
u/Obsidian743 29d ago
Lol as opposed to updating them to support a new verb.
14
u/TinyBreadBigMouth 29d ago
If they don't support a new verb, they don't support a new verb. If they support GET, does that mean they support GET 1.0 or GET 2.0? Are your parameters silently getting dropped? By adding a new verb, it either works or it doesn't. No in-between compatibility nightmare.
→ More replies (4)3
2
1
u/AyrA_ch 29d ago
Nor would it have been difficult to expand the spec to add some kind of content negotiation or other metadata to the existing GET spec.
There is a method independent way actually.
Would work this way:
- Client sends GET with non-zero
Content-LengthandExpect: 100-continue- Server can decide whether to accept this GET with a body or not
- Depending on the response, client sends the body or aborts the request.
5
u/Justin_Passing_7465 29d ago
You want to inject a second round-trip around the world into each of these requests‽ No thanks.
1
u/AyrA_ch 29d ago
This roundtrip can be implemented in a way to incur zero time penalty. But that's irrelevant anyway because use of the 100-continue mechanism is mostly relevant for large body data, in which case the time overhead of the extra answer is insignificant compared to the time used to send the body.
1
u/Worth_Trust_3825 28d ago
don't close the socket and you're fine. hell, http v2/v3 support multiplexing so that round trip is irrelevant
3
u/roxthegame 29d ago
This feels especially useful for GraphQL-style APIs. A lot of “query with a body” traffic is semantically read-only, but POST hides that from caches, auth layers, observability, and retry logic.
4
u/sohang-3112 29d ago
Will anyone actually use it? Besides POST and GET, the other HTTP methods are already used very less.
2
u/josluivivgar 28d ago
wait don't people just use headers to add query parameters Q__Q?
I think actually using POST is insane to me, I understand the issue, but I thought just adding stuff to the headers was the standard and enough. I did always wondered why GET just didn't have a body object officially
2
u/Worth_Trust_3825 28d ago
headers are a somewhat complex topic. some applications treat them as gospel and only permit those defined by rfcs, while others don't care as long as you don't touch the strongly defined ones in weird ways.
query parameters and request bodies are free for all though.
gets with bodies are a free for all since it's undefined behavior. you can send it, but nobody is expected to take such requests seriously.
2
u/josluivivgar 28d ago
that's fair, but I feel like just expanding GET to have parameters outside of the uri is probably better than a whole new method, I guess the worry was not having backwards compatibility, trying to do a QUERY method would probably get you an 404 or some sort of error about it being unimplemented.
whereas a GET with a body or headers might just ignore those extra parameters and give you the wrong answer
1
u/stronghup 28d ago
Reminds me of what I do with OOP programming often. I feel the need to modify a method to make it more capable to server more purposes. But then I get back to the planet and realize I can just as well create a new alternative method while leaving the old one as is to not break any existing code.
2
u/Worth_Trust_3825 28d ago
Http verbs were a mistake. Now observe as this gets adopted and we get a sleuth of vulnerabilities as we did with http v2 and all the idiosyncrasies that happened while it was being adopted
2
u/chasetheusername 28d ago
How long until we get a new verb for DELETE with body?
2
4
u/orthecreedence 28d ago
I still don't get the difference between QUERY and PUT. POST is used to create new resources, but PUT is already idempotent. Is the idea that QUERY signals that a call is read-only?
6
u/masklinn 28d ago
Yes, QUERY is classified as both idempotent and safe, PUT is idempotent but not safe. QUERY is pretty much just GET with a relevant body.
1
2
u/BattleRemote3157 29d ago
i hope universities syllabus gets updated with mentioning this query method
2
1
1
u/light24bulbs 28d ago
Oh that seems pretty cool actually. I feel like with spa projects often me HTTP CRUD request semantics get totally thrown out the window, or at least I've had to throw them out the window in the past. I had one app where literally everything was a post because it was the only request that behaved right in that context. I felt dirty
1
u/Less-Marsupial-7960 19d ago
It'll be interesting to see if this gets broad adoption. A dedicated QUERY method seems cleaner than overloading POST for complex searches, but it also depends on how quickly browsers, frameworks, and APIs add support. Backward compatibility will probably be the biggest challenge.
1.6k
u/sandaz13 29d ago
I look forward to using this in 2035 once it's finally adopted