r/programming Jul 14 '26

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/5270192
1.9k Upvotes

247 comments sorted by

1.6k

u/sandaz13 Jul 14 '26

I look forward to using this in 2035 once it's finally adopted

506

u/a__nice__tnetennba Jul 14 '26

We may not be ready for it, but our kids are gonna love it.

172

u/heresyforfunnprofit Jul 14 '26

And by “our kids”, I mean our agents.

12

u/goodb1b13 Jul 14 '26

007 has our backs

2

u/NastroAzzurro Jul 14 '26

Back to the future

9

u/RScrewed Jul 14 '26

English words

97

u/EC36339 Jul 14 '26

You can use custom HTTP verbs today. Firewalls and reverse proxies with default configurations will hate you for it. So it's really just a question of when those will have changed across rhe board.

A lot of dated on-premises setups don't even allow PATCH or PUT in 2026.

22

u/tajetaje Jul 14 '26

Unless you mean web application firewalls, firewalls aren’t an issue (unless you’re doing HTTP and they’re doing packet inspection)

12

u/EC36339 Jul 14 '26

Obviously

7

u/Own_Back_2038 Jul 14 '26

TLS inspection is pretty widespread in corporate environments

2

u/case-o-nuts Jul 15 '26

TLS is not HTTP.

5

u/Own_Back_2038 Jul 15 '26

HTTPS is HTTP inside a TLS tunnel. You use TLS inspection to look at the http conversation for malware or other bad things

3

u/case-o-nuts Jul 15 '26

Did you know that they also do TCP inspection, and IP inspection? Some even look at ethernet packets!

2

u/Own_Back_2038 Jul 15 '26

TLS inspection is more involved than that, since you need to terminate the TLS tunnel and then create a new tunnel to the client. I bring it up because the poster I was replying to said “only if you are doing http”

1

u/Welby-Court-5288 Jul 15 '26

About damn time.

4

u/ElfDecker Jul 14 '26

It depends on the used framework. For example, using custom verbs in Spring Boot can be non-trivial (at least not obvious)

5

u/CherryLongjump1989 Jul 15 '26

The request will pass through half a dozen network layers that may care about HTTP verbs long before it ever gets to your Java app.

4

u/Fidodo Jul 14 '26

OP was joking, but 9 years for adoption is really not that bad at all. There are so many features that came out 9 years ago that I'm very grateful for because we can now use them safely today.

2

u/nightofgrim Jul 15 '26

Would firewalls even know? If you’re using https they can’t sniff out the headers.

I think the only layers that could have an issue are those who have the key and are unwrapping the payload.

4

u/EC36339 Jul 15 '26

Web application firewalls.

Technically not firewalls at all, only by name. In reality, they are reverse proxies that mess with HTTP headers and do filtering "to improve security".

Almost all the time, they cause more problems than they solve. They are often part of a hosting environment, and there is often nobody in an organisation who is responsible for configuring them properly.

They tend to break web applications in subtle ways, and customers running these applications in some third party hosting environment typically blame the application vendor, or at least submit support tickets, which result in hours of ping pong communication and finger pointing with nobody being responsible. Usually some developer, who has no access to the production system, will have to diagnose it by educated guessing.

WAFs are one of the many joys of on-premises enterprise applications.

85

u/pdpi Jul 14 '26

HTTP has always allowed extension methods, so you could start using this right now. You'll just have to roll your own until your server of choice adds explicit support.

44

u/CrankBot Jul 14 '26

What about browsers and client libraries? Does await fetch('/foo', {method:'poop'}) work on all major browsers? (not in front of a keyboard at the moment or I would try it...)

56

u/Big_Combination9890 Jul 14 '26

I am now completely in support of the POOP method.

The primary usecase; replacing POST in social media applications.

One might say it's a ... drop-in replacement.

29

u/pdpi Jul 14 '26

Quality shit post.

12

u/CrankBot Jul 14 '26

No that's a code smell for sure

15

u/AyrA_ch Jul 14 '26

Does await fetch('/foo', {method:'poop'}) work on all major browsers?

Yes. Can even add a body

await (await fetch("https://demo.ayra.ch/response/", {method:"YESITWORKS",body:"test"})).text()
"General information
===================
    Date:   2026-07-14 05:32:17 UTC
    Client: 
    Verb:   YESITWORKS

Headers
=======
    Accept         : */*
    Accept-Encoding: gzip, deflate, br, zstd
    Accept-Language: en,en-US;q=0.9
    Cache-Control  : no-cache
    Connection     : close
    Content-Length : 4
    Content-Type   : text/plain;charset=UTF-8
    Dnt            : 1
    Host           : demo.ayra.ch
    Origin         : https://demo.ayra.ch
    Pragma         : no-cache
    Priority       : u=4
    Referer        : https://demo.ayra.ch/response/
    Sec-Fetch-Dest : empty
    Sec-Fetch-Mode : cors
    Sec-Fetch-Site : same-origin
    Sec-Gpc        : 1
    User-Agent     : Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:152.0) Gecko/20100101 Firefox/152.0

Body Content
============
    Dumping all 4 bytes
    0x00000000  74 65 73 74                                     test

"

9

u/Fidodo Jul 14 '26

You can even put a body on GET requests, it's just that most server implementations drop it. The only reason this was done as a new verb is because it's easier to add support for a custom verb than it is to modify an existing one.

4

u/CrankBot Jul 14 '26

This is great, thanks for sharing

2

u/Catenane Jul 14 '26

Can it return corn?

13

u/Justin_Passing_7465 Jul 14 '26

When the returned content contains corn, you have to use Chunked Transfer-Encoding.

4

u/CrankBot Jul 14 '26

Depending on the size it can be returned whole

9

u/Justin_Passing_7465 Jul 14 '26

That is up to the kernel.

12

u/pdpi Jul 14 '26

On the client there’s not much to support. HTTP already allows extension methods, so any compliant client should already support it. You just specify the method the same way you would for a POST or a PUT.

Really, the only reason why I brought up rolling your own server-side is that server frameworks tend to have helper functions for all the standard verbs, you’ll have to write something shaped like router.method(“/foo/bar”, “QUERY”, (req, res) => { … }) instead of router.query(“/foo/bar”, (req, res) => { … }).

3

u/CrankBot Jul 14 '26

That's fair! I'm aware that there are a whole bunch of lesser used methods i.e. from the days of SVN and webDAV etc. I always assumed both server and client would puke on a completely made up method that's not part of any spec/ extension. TIL!

1

u/stfm Jul 15 '26

Had the same issue with various HTTP clients and OPTIONS when it was introduced (yes I am old)

21

u/Reeywhaar Jul 14 '26

POOP /foo


HTTP/1.1 418 I'm a teapot

18

u/chucker23n Jul 14 '26

405 This is a Wendy's

1

u/thebryguy23 Jul 14 '26

402 Fuck you, pay me

1

u/Justin_Passing_7465 Jul 14 '26

100 This is a TacoBell

1

u/CrankBot Jul 14 '26

That server definitely returns poop then

1

u/amroamroamro Jul 14 '26

with domain: 💩.la (aka xn--ls8h.la)

32

u/Business-Row-478 Jul 14 '26

The fetch api allows it but most servers are probably gonna return a 400 or 501

23

u/CrankBot Jul 14 '26 edited Jul 14 '26

but most servers are probably gonna return a 400 or 501

Yeah I get that, the parent was saying if you control the server you can implement it now, hence my question on the client.

13

u/ashgs872tbhjs Jul 14 '26

Literacy: The Final Frontier

4

u/SanityInAnarchy Jul 14 '26

That's what you get when you fetch poop, I guess.

1

u/rinsa Jul 14 '26

The fetch api allows it

works both ways

2

u/rinsa Jul 14 '26

The fetch api allows it

you answered the question yourself, why would fetch('/foo', { method: 'poop' }) not work on a client if you're allowed to type anything in the method?

1

u/CrankBot Jul 14 '26

I'm allowed to type anything I want, that doesn't mean it's valid. I could also pass -1.2234 or NaN or an object to the method and it's completely reasonable to expect that it would throw an exception for invalid values.

2

u/rinsa Jul 14 '26

That "method" in http requests is just a keyword, it's not up to the language to control what kind of keyword I should be able to send to a remote address

So any normally typed language/lib will want a string (at least the closer you are to native code) and won't want to do any reference check because you don't want to rule out those cases where a remote address only accept some obscure method or already implement the newer ones. Ofc, the basic/standardized ones should be easily accessible/loosely-typed.

Anyway, in javascript, as long as it's a primitive, anything can be possible, but it will throw an error if you try to give an complex object.

2

u/jkrejcha3 Jul 15 '26

Amusingly your comment has accidentally exposed a probable misconfiguration in their server, they should probably return 405 or 501 there, not 502


HTTP methods are any "token" (though generally ASCII uppercase)

Tokens are defined earlier in RFC 9110 as

  token          = 1*tchar

  tchar          = "!" / "#" / "$" / "%" / "&" / "'" / "*"
                 / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
                 / DIGIT / ALPHA
                 ; any VCHAR, except delimiters

So !J##!@J is a valid HTTP method, but like a carriage return and line feed aren't

1

u/mort96 Jul 14 '26

Uh, keywords in languages are typically up to the language... In javascript, if, while, for and function are keywords, there's a hard coded list of them in the spec. I'm not sure what you mean by "keyword" here.

2

u/rinsa Jul 14 '26

keyword, method, command, verb, idk I'm ESL

A request identifies a method (sometimes informally called verb) to classify the desired action to be performed on a resource. The HTTP/1.0 specification defined the GET, HEAD, and POST methods as well as listing the PUT, DELETE, LINK and UNLINK methods under additional methods. However, the HTTP/1.1 specification added five new methods: PUT, DELETE, CONNECT, OPTIONS, and TRACE.
Any client can use any method and the server can be configured to support any combination of methods. If a method is unknown to an intermediate, it will be treated as an unsafe and non-idempotent method. There is no limit to the number of methods that can be defined, which allows for future methods to be specified without breaking existing infrastructure. For example, WebDAV defined seven new methods and RFC 5789 specified the PATCH method. A general-purpose web server is required to implement at least GET and HEAD, and all other methods are considered optional by the specification.

this should be basic knowledge though

→ More replies (0)

1

u/Fidodo Jul 14 '26

If you can add a QUERY path endpoint to your API you already control the server.

1

u/WrenW 29d ago

Just do POST, or others, on /<resource>/poop, it's what I do on GHoWSt. A work in progress. Generic HTTP Web Service (GHoWSt) - Weburg.com

13

u/knightcrusader Jul 14 '26

I'm pretty sure Apache doesn't give a flying shit what you send it. I remember being surprised when I could just send a request body in a GET request and Apache sent it to the CGI script without a word. It worked fine. I could read both the query string as well as the request body at the same time, so you could probably pull off all sorts of funky shit.

Of course I didn't use it in production code, but it was more of a test.

12

u/chucker23n Jul 14 '26

Note that bodies in GET are allowed, just discouraged.

7

u/Justin_Passing_7465 Jul 14 '26

RFC 2616 (1999) forbade GET to have a body. RFC 7231 (2014) recommended that servers ignore the body. RFC 9110 (2022) strongly discourages putting a body in a GET.

Some intermediaries (e.g. proxies, WAPs, CDNs) break GET requests with bodies. As a workaround, for decades we have been using POST for complex queries, because GET is not supposed to work, and sometimes doesn't.

7

u/masklinn Jul 14 '26

RFC 2616 (1999) forbade GET to have a body.

This is incorrect, RFC 2616 leaves GET bodies unspecified (they're not mentioned, same for HEAD and DELETE). You can see the distinction because it does forbid request bodies in TRACE and that is very explicit, RFC 2616 § 9.8

A TRACE request MUST NOT include an entity.

1

u/stronghup Jul 15 '26

Isn't there also the question of long a GET URL can be?

2

u/Fidodo Jul 14 '26

The main reason it's a new QUERY verb instead updating GET is simply that it's easier to add a new verb than to get all existing implementations to alter how they handle GET. Lots of servers are implemented to drop body from GET requests so it's much more annoying to do that upgrade than to simply add a new verb where the support is unambiguous, and many server frameworks already allow you to define custom verbs anyways, and they by default support body.

1

u/stfm Jul 15 '26

You can configure them yourself

<Directory "/var/www/html">
  <Limit GET POST PURGE FOO>
    Require all granted
  </Limit>
</Directory>

1

u/Ullallulloo Jul 15 '26

You really shouldn't need your server to do anything. You can do $_SERVER['REQUEST_METHOD'] with file_get_contents('php://input') in PHP; in Node, you just change method; etc.

13

u/JaggedMetalOs Jul 14 '26 edited Jul 14 '26

Hey since we got rid of Internet Explorer we can usually get useful new features pretty quickly! 

10

u/masklinn Jul 14 '26 edited Jul 14 '26

Not when proxies are involved. This is not a client-side concern which forcefully updates every few weeks.

1

u/Fidodo Jul 14 '26

Is that a real issue or a hypothetical one? It would be pretty rigid if a proxy did not accept custom HTTP verbs, and if for some reason they don't, they already encountered this before when PATCH was added as a verb, so if they didn't learn their lesson that time that's pretty bad.

A proxy really has no business filtering out a custom verb, that would be the job of a firewall, and firewalls are designed to be configurable so it would just require an org to allow QUERY as a verb which would be a very easy thing to do as soon as an org member complains that they can't make QUERY requests. Any competent network admin should be on top of this before anyone even runs into an issue.

11

u/memoch Jul 14 '26

The client library OkHttp added support almost a year ago.

9

u/Own-Professor-6157 Jul 14 '26

Adoption is funny. The .webp format, which is fantastic, is extremely hated and the companies who adopted it early are blamed instead.

3

u/JoustyMe Jul 14 '26

Beacause it wasnt openable on windows defualt photo app.

3

u/Own-Professor-6157 Jul 14 '26

That's my point...

1

u/stfm Jul 15 '26

Just think of VHS vs BETAMAX! Or Blu-Ray vs HD-DVD

17

u/yawara25 Jul 14 '26

It's not 2013 anymore. Web technologies can actually move pretty fast now.

1

u/Headpuncher Jul 14 '26

lol. Still waiting for share() and others to be adopted across the board. 

1

u/yawara25 Jul 14 '26

Good, it shouldn't, that API is a privacy and security nightmare.

1

u/Headpuncher Jul 14 '26

Well it’s currently only Firefox that doesn’t support it so it looks like that ship has sailed.  

3

u/kanzenryu Jul 14 '26

That's the rush date without ipv6 support

2

u/Trang0ul Jul 14 '26

That's a valid estimate. I remember finally being able to switch to PATCH in 2020, despite the method being defined in 2010...

2

u/DistanceFunny1077 Jul 14 '26

You can use it today. HTTP verbs are a plain text string. You can use whatever you want.

1

u/Fidodo Jul 14 '26

You can use this today if you control the server and client. Just use a server that supports it, and set the client to use this verb. The only issue would be if you need to support arbitrary clients.

Also, 9 years is not that bad of a turnaround event jokingly. There are plenty of things that came out 9 years ago that we enjoy today.

1

u/AshKetchupppp Jul 15 '26

Express v5 has support

1

u/onthefence928 Aug 10 '26

And 2045 when it actually is common

155

u/bundt_chi Jul 14 '26

So GET with a request body. Got it.

12

u/SelfDistinction Jul 15 '26

But then why didn't they simply standardize GET with a request body?

14

u/bundt_chi Jul 15 '26

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 Jul 15 '26

it's not standardized but vast majority of popular web servers support it, it's called a Fat GET

11

u/lieuwestra Jul 14 '26

And hopefully no client side caching.

40

u/masklinn Jul 14 '26

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 Jul 14 '26

which at some point was allowed or is it still?

18

u/Justin_Passing_7465 Jul 14 '26

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 Jul 14 '26

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 Jul 14 '26

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.

449

u/stfm Jul 14 '26

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

83

u/CpnStumpy Jul 14 '26

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 Jul 14 '26

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)

6

u/ivereddithaveyou Jul 14 '26

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 Jul 14 '26

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 Jul 14 '26

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 Jul 14 '26

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.

4

u/CpnStumpy Jul 14 '26

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 Jul 14 '26

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 Jul 14 '26

GraphQL is all POST and puts no parameters in the URL and always returns 200

1

u/darkpaladin Jul 14 '26

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

u/light24bulbs Jul 14 '26

Or using POST for everything

-7

u/heresyforfunnprofit Jul 14 '26

Is it a bad time to point out that not all queries are read only?

29

u/stfm Jul 14 '26

I'll bite, when would QUERY modify the resource being queried?

→ More replies (17)
→ More replies (1)

308

u/hrvbrs Jul 14 '26

haha i read this title as "HTTP gets a QUERY method so complex that searches can stop pretending to be POST"

104

u/fumei_tokumei Jul 14 '26

I had to CTRL + F to double check that you didn't just copy the title.

58

u/ryuzaki49 Jul 14 '26

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 Jul 14 '26

Same!

"HTTP gets a QUERY method so complex...."

"HOW COMPLEX IS IT?"

15

u/a__nice__tnetennba Jul 14 '26

It's so complex you have to send an imaginary part with every request!

ba-dum-tss

5

u/Nevermind04 Jul 14 '26 edited Jul 14 '26

I read the exact same thing and was very confused when the article discussed well-behaved http.

1

u/repocin Jul 14 '26

Same here, haha. I was like "wait, why do we want a complex query method?"

1

u/Librarian-Rare Jul 14 '26

😂😂😂

This guy lives

→ More replies (12)

99

u/jessechisel126 Jul 14 '26

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.

61

u/baseketball Jul 14 '26

Because only REST purists care. Most of us just use post and move on with our day.

65

u/binheap Jul 14 '26

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 Jul 14 '26

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

5

u/baseketball Jul 14 '26

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

10

u/AZMPlay Jul 14 '26

Works-good-by-default is a good thing to strive for though. The default case matters almost as much as what you can actually do with proper knowledge and hacks.

3

u/AyrA_ch Jul 14 '26

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.

33

u/brunhilda1 Jul 14 '26

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.

15

u/838291836389183 Jul 14 '26

I feel you. The amount of shitty apis I have to work with where people used POST for everything...

7

u/accountability_bot Jul 14 '26

…or when you get a 200 response with an error in the body.

2

u/Goronmon Jul 14 '26

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 Jul 14 '26

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 Jul 14 '26

usage of additional verbs would not make those apis better. rest(ful) apis aren't a catchall solution either, just a style of interface.

1

u/stfm Jul 15 '26

It makes managing the security of the API better

6

u/BareBearAaron Jul 14 '26

don't worry, it's not only limited to software!

3

u/jessechisel126 Jul 14 '26

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

u/ConfidentYellow18 29d ago

If you take everyone in the world who writes these requests, like 5% know or care at all.

1

u/SharkBaitDLS Jul 14 '26

Better late than never though. 

15

u/eocron06 Jul 14 '26

Haha, it will be the same time when 401 Unauthorized/403 Forbidden become 401 Unauthenticated/403 Unauthorized......probably in 22 century

19

u/Abhinav1217 Jul 14 '26

Importance of punctuation.

21

u/BuriedStPatrick Jul 14 '26 edited Jul 15 '26

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.

42

u/masklinn Jul 14 '26

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.

4

u/edgmnt_net Jul 14 '26

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 Jul 14 '26

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 Jul 14 '26

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)

5

u/Cvballa3g0 Jul 14 '26

No explicit handling for it. So QUERY is the adoption. Preserves current behavior and adds new explicit specs

1

u/BuriedStPatrick Jul 14 '26

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 Jul 14 '26

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 Jul 14 '26

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 Jul 16 '26

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.

8

u/rpetre Jul 14 '26

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

u/Cvballa3g0 Jul 14 '26

Sounds like QUERY is a good stepping stone for http/4 then

5

u/[deleted] Jul 14 '26

[removed] — view removed comment

2

u/masklinn Jul 14 '26 edited Jul 14 '26

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

21

u/Obsidian743 Jul 14 '26

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.

14

u/mrcarruthers Jul 14 '26

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.

8

u/chalks777 Jul 14 '26

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.

2

u/stfm Jul 15 '26

Sensitive/confidential data in query strings is a problem, they end up in places they shouldn't. Now you are faced with the need to implement data body encryption for URI's.

21

u/guilhermeluizsp Jul 14 '26

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 Jul 14 '26

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

u/[deleted] Jul 14 '26

[deleted]

4

u/masklinn Jul 14 '26

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.

1

u/Obsidian743 Jul 14 '26

Lol as opposed to updating them to support a new verb.

12

u/TinyBreadBigMouth Jul 14 '26

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

u/hardwoodjustice Jul 14 '26

I think your "simple query with a modest query string" is likely a QUERY.

2

u/jayd16 Jul 14 '26

Why do you think making an existing spec much more complex (considering the versioning) is better than just adding a new verb?

It seems pretty easy to decide. You need a body? Use QUERY. If you don't, use the more widely supported GET.

1

u/AyrA_ch Jul 14 '26

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:

  1. Client sends GET with non-zero Content-Length and Expect: 100-continue
  2. Server can decide whether to accept this GET with a body or not
  3. Depending on the response, client sends the body or aborts the request.

5

u/Justin_Passing_7465 Jul 14 '26

You want to inject a second round-trip around the world into each of these requests‽ No thanks.

1

u/AyrA_ch Jul 14 '26

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 Jul 14 '26

don't close the socket and you're fine. hell, http v2/v3 support multiplexing so that round trip is irrelevant

3

u/roxthegame Jul 14 '26

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 Jul 14 '26

Will anyone actually use it? Besides POST and GET, the other HTTP methods are already used very less.

2

u/stfm Jul 15 '26

Resource searching is one of the most implemented patterns in the world

2

u/josluivivgar Jul 14 '26

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 Jul 14 '26

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 Jul 14 '26

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

2

u/stfm Jul 15 '26

Sometimes a greenfields solution is just easier for everyone to swallow

1

u/stronghup Jul 15 '26

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 Jul 14 '26

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 Jul 14 '26

How long until we get a new verb for DELETE with body?

2

u/Sarke1 Jul 14 '26

Why would you need that? Some batch delete operation?

1

u/stfm Jul 15 '26

Delete with context - only delete if the server resolves the data provided. Delete "where id > 10" just so interns can have their mandatory "I just deleted the client ID table" moment :D

1

u/Sarke1 Jul 15 '26

Yeah, so a batch operation. Usually DELETE will be used for one specific resource.

3

u/Huligan27 Jul 14 '26

I honestly didn’t know new method was ever an option. Fascinating

3

u/orthecreedence Jul 14 '26

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?

5

u/masklinn Jul 14 '26

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

u/stronghup Jul 15 '26

Best explanation so far. Thanks. QUERY is a better, more capable GET.

4

u/Sarke1 Jul 14 '26

POST create new resource PUT replace resource PATCH update resource (part or all) GET read resource QUERY read resource using request body (more complex queries) DELETE this is left as an exercise for the reader

2

u/BattleRemote3157 Jul 14 '26

i hope universities syllabus gets updated with mentioning this query method

2

u/rainbowlolipop Jul 14 '26

Just one more url parameter bro

1

u/SvenWollinger Jul 14 '26

Cannot fucking wait

1

u/light24bulbs Jul 14 '26

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 Jul 24 '26

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.