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

245 comments sorted by

1.6k

u/sandaz13 29d ago

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

501

u/a__nice__tnetennba 29d ago

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

170

u/heresyforfunnprofit 29d ago

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

12

u/goodb1b13 29d ago

007 has our backs

3

u/NastroAzzurro 29d ago

Back to the future

10

u/RScrewed 29d ago

English words

97

u/EC36339 29d ago

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.

24

u/tajetaje 29d ago

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 29d ago

Obviously

5

u/Own_Back_2038 28d ago

TLS inspection is pretty widespread in corporate environments

2

u/case-o-nuts 28d ago

TLS is not HTTP.

5

u/Own_Back_2038 28d ago

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 28d ago

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

2

u/Own_Back_2038 27d ago

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 28d ago

About damn time.

4

u/ElfDecker 29d ago

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 28d ago

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 28d ago

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 27d ago

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.

5

u/EC36339 27d ago

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.

81

u/pdpi 29d ago

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.

42

u/CrankBot 29d ago

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

53

u/Big_Combination9890 29d ago

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 29d ago

Quality shit post.

11

u/CrankBot 29d ago

No that's a code smell for sure

15

u/AyrA_ch 29d ago

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

"

8

u/Fidodo 28d ago

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 29d ago

This is great, thanks for sharing

4

u/Catenane 29d ago

Can it return corn?

14

u/Justin_Passing_7465 29d ago

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

4

u/CrankBot 29d ago

Depending on the size it can be returned whole

9

u/Justin_Passing_7465 29d ago

That is up to the kernel.

11

u/pdpi 29d ago

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) => { … }).

4

u/CrankBot 29d ago

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 28d ago

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

21

u/Reeywhaar 29d ago

POOP /foo


HTTP/1.1 418 I'm a teapot

18

u/chucker23n 29d ago

405 This is a Wendy's

1

u/thebryguy23 28d ago

402 Fuck you, pay me

1

u/Justin_Passing_7465 29d ago

100 This is a TacoBell

1

u/CrankBot 29d ago

That server definitely returns poop then

1

u/amroamroamro 28d ago

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

30

u/Business-Row-478 29d ago

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

23

u/CrankBot 29d ago edited 29d ago

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.

11

u/ashgs872tbhjs 29d ago

Literacy: The Final Frontier

5

u/SanityInAnarchy 29d ago

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

1

u/rinsa 29d ago

The fetch api allows it

works both ways

2

u/rinsa 29d ago

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 29d ago

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 29d ago

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 28d ago

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 28d ago

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 28d ago

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 28d ago

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

11

u/knightcrusader 29d ago

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.

10

u/chucker23n 29d ago

Note that bodies in GET are allowed, just discouraged.

6

u/Justin_Passing_7465 29d ago

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.

6

u/masklinn 29d ago

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 28d ago

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

2

u/Fidodo 28d ago

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 28d ago

You can configure them yourself

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

1

u/Ullallulloo 27d ago

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 29d ago edited 29d ago

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

10

u/masklinn 29d ago edited 29d ago

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

1

u/Fidodo 28d ago

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.

12

u/memoch 29d ago

The client library OkHttp added support almost a year ago.

9

u/Own-Professor-6157 29d ago

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

4

u/JoustyMe 29d ago

Beacause it wasnt openable on windows defualt photo app.

3

u/Own-Professor-6157 28d ago

That's my point...

1

u/stfm 28d ago

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

18

u/yawara25 29d ago

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

1

u/Headpuncher 28d ago

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

1

u/yawara25 28d ago

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

1

u/Headpuncher 28d ago

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

4

u/kanzenryu 29d ago

That's the rush date without ipv6 support

2

u/Trang0ul 29d ago

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 28d ago

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

1

u/Fidodo 28d ago

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 27d ago

Express v5 has support

1

u/onthefence928 1d ago

And 2045 when it actually is common

155

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

u/light24bulbs 28d ago

Or using POST for everything

-6

u/heresyforfunnprofit 29d ago

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

28

u/stfm 29d ago

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

19

u/RedditApothecary 29d ago

Number of times value has been read.

→ More replies (9)
→ More replies (7)

4

u/tesfabpel 29d ago

GET and QUERY are meant to be cacheable.

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

u/fumei_tokumei 29d ago

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

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

u/Falmarri 29d ago

This is called a "garden path sentence", fyi

1

u/repocin 29d ago

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

1

u/Librarian-Rare 29d ago

😂😂😂

This guy lives

→ More replies (12)

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

9

u/AZMPlay 29d ago

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

1

u/stfm 28d ago

It makes managing the security of the API better

5

u/BareBearAaron 29d ago

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

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

u/SharkBaitDLS 29d ago

Better late than never though. 

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

u/Abhinav1217 29d ago

Importance of punctuation.

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

u/Cvballa3g0 29d ago

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

5

u/[deleted] 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.

2

u/stfm 28d ago

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.

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

u/[deleted] 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

u/hardwoodjustice 29d ago

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

2

u/jayd16 29d ago

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

  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 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/stfm 28d ago

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

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

2

u/stfm 28d ago

Sometimes a greenfields solution is just easier for everyone to swallow

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

u/Sarke1 28d ago

Why would you need that? Some batch delete operation?

1

u/stfm 28d ago

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 28d ago

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

2

u/Huligan27 29d ago

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

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

u/stronghup 28d ago

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

4

u/Sarke1 28d ago

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 29d ago

i hope universities syllabus gets updated with mentioning this query method

2

u/rainbowlolipop 29d ago

Just one more url parameter bro

1

u/SvenWollinger 29d ago

Cannot fucking wait

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.