HTTP has a new method: QUERY. Tl;dr: GET with a body.

https://www.ietf.org/archive/id/draft-ietf-httpbis-safe-method-w-body-14.html

(Doesn’t have an RFC number yet but has been approved, will get one in a few weeks.)

#ietf

The HTTP QUERY Method

This specification defines the QUERY method for HTTP. A QUERY requests that the request target process the enclosed content in a safe and idempotent manner and then respond with the result of that processing. This is similar to POST requests but can be automatically repeated or restarted without concern for partial state changes.

@timbray *Technically* there's no spec reason that GET can't have a body as it is (as far as I remember), but when I tried it with something a lot of stuff became unhappy.

@eythian @timbray

Made the same discovery a few years ago. Also technically you can use any word and not just "GET, POST, ..." and some APIs do...

@agowa338 @eythian @timbray yep. works just fine with curl. I kinda always assumed it was fine because like. obviously it's useful. equally obviously it's niche, but it's not like it's an unheard-of thing when urls/params are frequently length-limited.
@eythian @timbray I've even seen DELETE with a body in the Matrix spec
Client-Server API

The client-server API allows clients to send messages, control rooms and synchronise conversation history. It is designed to support both lightweight clients which store no state and lazy-load data from the server as required - as well as heavyweight clients which maintain a full local persistent copy of server state. API Standards These standards only apply to the APIs defined in the Matrix specification. APIs used by this specification but defined in other specifications, like the OAuth 2.0 API, use their own rules.

Matrix Specification
@timbray @eythian Technically you can, but technically it has no semantic meaning so you can't do anything useful with it. Any HTTP message can have a body. However only some methods allow the body to have meaning for the request. GET and DELETE don't, POST and QUERY do.
It's a layering thing in the design.
@darrel_miller
In my case I was building a thing that basically allowed throwing JSON over HTTP (normally I'd say RESTish but that has its own semantics so would just confuse things because it wasn't really that.) But we found that while our Perl stuff was fine with it, the Java libraries just couldn't handle it, and I think some load balancers also got upset. You're right that it's not very HTTPish but we were just using that as a transport layer really so the semantics wouldn't have mattered all that much.
@timbray

@eythian I imagine this is largely as a... I guess backwards compatibility safety? Rather than change the spec on servers that don't expect it, introduce a better verb for such purpose that'll ensure servers respond appropriately always.

@timbray I like this idea a lot, and I hope once approved some of the vendors I work with will introduce it. Sending `?filter={"criteria":{...}}` as a URL GET argument is turbo clunky and POST isn't really right for getting info either.

I wonder if this will alter GraphQL endpoints to start preferring a QUERY verb for read-only `query` requests to delegate POST for `mutate` requests.

@eythian @timbray And I've seen GET queries with JSON bodies in some APIs years ago...
@timbray So, the same as POST but with different semantics?
@fell @timbray And the assurance that you don't change a state on the back-end. By definition POST requests imply that something is changed, where as GET request shouldn't mutate anything.
@timbray Could have made good use of this the other day when we implemented a download API with a non-trivial request and had to do this with a POST-REDIRECT-GET cycle.
@timbray APIs have needed this for decades. It's fine for web sites to just have a query string, but API requests need queries that just don't fit or can't be properly encoded without resorting to a base64 blob. We've abused POST for this, but that's a bad solution.
@timbray do you know why they didn't "just" define the semantics of the GET body? I assume the answer is "backwards compatibility"…

@timbray I'm torn. I'm a huge fan of the URL as a transparent representation of state (for bookmarking, sharing, and even just reading/editing in the location bar).

Sure, for big queries, the alternatives are POST (bad UI), POST-and-redirect (not bookmarkable/sharable unless you're careful), or AJAX (both). So QUERY is potentially a UX improvement. It also may be ripe for overuse, a degradation of what could've been GET pages.

But yeah, SDOs should be descriptive, not prescriptive.

@twifkak @timbray the RFC does address that using Location and Content-Location headers. Basically allowing a server to save the query and/or the result at a GET-able URI and provide it to the client. Similar to POST-and-redirect but with better-defined semantics.
@timbray Huh, I thought of it as "POST with idempotent safety".
@paulehoffman No, it's really different. POST is expected to change the state of the target resource and can incur obligations; but that doesn't apply to either GET or QUERY.
@timbray it’s not easy to introduce new http method, because there are too many middle-box like Nginx to be updated 🤦‍♂️
@timbray finally! This reminds me of this Chinese proverb about planting a tree.

@timbray wow, what's happening! That's a cool new thing.

I still hope browsers will support PATCH and friends too from forms one day

@timbray at last, this is so needed for simplifying caching strategies.
@timbray only took six years? Win.
@timbray Fantastic, this only took about three decades!
@timbray Technically, GET with a body was never forbidden, just had "no defined semantics" and could "cause some existing implementations to reject the request" https://datatracker.ietf.org/doc/html/rfc7231#section-4.3.1:~:text=A%20payload%20within%20a%20GET%20request%20message%20has%20no%20defined%20semantics 🤷
RFC 7231: Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content

The Hypertext Transfer Protocol (HTTP) is a stateless \%application- level protocol for distributed, collaborative, hypertext information systems. This document defines the semantics of HTTP/1.1 messages, as expressed by request methods, request header fields, response status codes, and response header fields, along with the payload of messages (metadata and body content) and mechanisms for content negotiation.

IETF Datatracker
@nurkiewicz @timbray It did get some extra SHOULD NOTs slapped on in RFC 9100 (which obsoleted 7231) though https://www.rfc-editor.org/rfc/rfc9110#name-get
RFC 9110: HTTP Semantics

The Hypertext Transfer Protocol (HTTP) is a stateless application-level protocol for distributed, collaborative, hypertext information systems. This document describes the overall architecture of HTTP, establishes common terminology, and defines aspects of the protocol that are shared by all versions. In this definition are core protocol elements, extensibility mechanisms, and the "http" and "https" Uniform Resource Identifier (URI) schemes. This document updates RFC 3864 and obsoletes RFCs 2818, 7231, 7232, 7233, 7235, 7538, 7615, 7694, and portions of 7230.

@timbray I've just spotted the first support for QUERY (that I've seen) in a web-framework - https://symfony.com/blog/new-in-symfony-7-4-misc-features-part-1#http-query-method
I've been interested in the idea for a while. Good to see it's getting results, even if it has been slow.
New in Symfony 7.4: Misc. Features (Part 1) (Symfony Blog)

Symfony 7.4 introduces faster native HTML5 parsing, more flexible URL validation, improved Link header handling, support for the HTTP QUERY method, and easier configuration of resource tags.

@timbray Finally we will have a reason to stop using graphql!!
@timbray i have seen a GET with a body in the wild years ago. i did not realize it was not in the spec. twas probably some PHP backend vs JS frontend

@timbray after all this time 🎉

Remember using and needing it with a GET and it working fine but then suddenly everyone started complaining and saying that it's broken because middle boxes and proxys fuck it up. I never saw it happen, but oh well. Let's see how this one goes.

@timbray Looks like a great idea; given how many people support PATCH requests vs overloading a POST request I question the wider support
@timbray I think it was more like POST, but can have an incomplete response.