top | item 36095032

Defining a new HTTP method: HTTP Search (2021)

171 points| thunderbong | 2 years ago |httptoolkit.com | reply

129 comments

order
[+] asattarmd|2 years ago|reply
One advantage of GET is I can just copy the URL and share it. The article makes no mention of that.

While I love the proposal (apart from the name, I can see the SEARCH verb being used for something that's not search), they should also address the URL share-ablity aspect.

Something like https://google.com/search<some-special-character><query> where query can be arbitrarily large (>2000 URL length restriction) and the browser is smart enough to treat only https://google.com/search as the URL and anything after that as the body. The complete "URL" can be big and shared anywhere else.

[+] hartator|2 years ago|reply
Yes, that’s also lost when you do POST. Which is by design though. A HTTP Search seems like only drawbacks.
[+] phailhaus|2 years ago|reply
The primary use case of SEARCH is programmatic, e.g., making complex requests to a search API in order to render results. Those are API requests, they're not being shared around.
[+] deepzn|2 years ago|reply
The proposal has changed the name to QUERY, just yesterday.
[+] BugsJustFindMe|2 years ago|reply
> One advantage of GET is I can just copy the URL and share it.

Often but not always.

The article is wrong when it says message bodies for GET are defined to be meaningless. They are in fact just not defined to be meaningful, which is very much not the same thing.

Nothing in the spec for GET blocks using message bodies with it. Elastic search famously uses(used?) bodies with GET requests.

[+] graypegg|2 years ago|reply
Guess that needs to be different than the ? query params. I wonder if you could use ?key=value as your signal for GET, and ?value as your signal for SEARCH. I think it's up to the service to parse the string that comes after ? in a URI so maybe that's a way to go.
[+] imnotjames|2 years ago|reply
This is why the RFC suggests you redirect to a GET like /resource/queryABCD
[+] candiddevmike|2 years ago|reply
Related, I wish there was a more standard way to include things like verb and headers in a URI. I hacked an implementation that parses /something#a:b&c:d to set the headers a and c, I was thinking for verb I could do https+get.
[+] 2h|2 years ago|reply
> One advantage of GET is I can just copy the URL and share it.

no, you cant. if the server requires any headers such as Authorization or Cookie, this method will fail.

[+] montroser|2 years ago|reply
This seems reasonable, but unlikely to happen. GET is already pretty much sufficient, especially given that clients generally support megabytes worth of query strings in these modern times. If we're doing this though, I'll cast my vote for naming it more semantically as QUERY, and forgoing whatever little WebDAV compatibility would be had otherwise.
[+] ZiiS|2 years ago|reply
QUERY would be more compatible with WebDAV as the would be no confusion. The relevant compatibility is with middle boxes like proxy servers that mostly already forward SEARCH but would block QUERY.
[+] wilg|2 years ago|reply
I’ve, amazingly, managed to hit the arbitrary megabyte limit in real production software.
[+] Raqbit|2 years ago|reply
Middle boxes can arbitrarily limit the request URL size in certain cases.
[+] yashap|2 years ago|reply
I’d like to see this (or something like it) ship. Right now the two most common alternatives are:

1) GET, but base64 encode a json payload as a query param. Main downsides are that you can hit URL size limits, it makes the client and server slightly more complex (base64 encode/decode), and it sucks with browser dev tools - can’t nicely inspect the request in the browser, have to copy and decode it

2) Use POST to search. This confuses both machines and people. On the machines side, it doesn’t play well with caches, retry middleware, etc. On the people side, it confuses developers, ppl monitoring metrics, etc. - you think it’s creating something but it isn’t. Basically goes against all the reasons we have separate GET/POST/PUT/PATCH/DELETE methods in the first place

Yeah, we have workarounds, but they have pretty significant downsides. I’d rather have this new method. Honestly, I think one of the main reasons ppl reach for RPC frameworks over RESTful APIs is the awkwardness around making search queries - this would really fix that issue.

[+] afiori|2 years ago|reply
I would say that people should be more open to using HTTP in non-REST ways.

Sometimes you want to send a request and receive a response, with arbirtrary restrictions and side effects that suit your cases.

There are a lot of good reason for rest to exists, but also sometime you want to POST /open-garage-door?t=5-minutes and call it a day

[+] hcarvalhoalves|2 years ago|reply

    Right now, you have two main options:
    
    Use a GET, and squeeze all the parameters you need in the URL or headers somewhere
    Use a POST, and have the request considered as unsafe & uncacheable
Third option: you POST or PUT to a resource representing the search, then you’re free to redirect and subsequently GETs of this resource can be cached.

Wanting a special method for search hurts the conceptual integrity of HTTP, where resource representation is the core idea to build on top, it isn’t supposed to be just a request/response protocol.

[+] leftnode|2 years ago|reply
That's exactly what we do: submitting a search/filter form through a POST request which creates a record in the database representing the search/filter criteria and then redirects to the same endpoint with the ID of that record. The endpoint looks for the ID in the query, attempts to load the same record, and if found, executes and returns the search results.

It works very well, is completely transparent to the end user, has automatic query logging, and provides a clean URL that can be easily shared.

[+] tedyoung|2 years ago|reply
> POST or PUT to a resource representing the search, then you’re free to redirect and subsequently GETs of this resource can be cached.

But that only means that specific instance of the search query is cacheable, not the search query itself, no? I presume the POST would create a new identifier for the resource, so that yes, that specific resource is cacheable. (Even if the server says "oh, I've just seen this POSTed query, let me return the same resource ID", another client will still have to POST to the server, a non-cacheable action.)

The idea of cacheable isn't just by the server, but by anything in between the client and the resource. By using QUERY, the query itself can be cached.

[+] mabbo|2 years ago|reply
What I like about this proposal is that no one has to use it. There's lots of comments here saying why they prefer GET, and those people are welcome to keep using it- GET will remain unchanged.

But for those applications where having a complex body in the query request is a better choice, this tool can be available. I think that's a win.

[+] zeroimpl|2 years ago|reply
TIL sending a POST request to a URL invalidates the cache for GET requests of the same URL.

Going to have to review my REST APIs to make sure that’s not a problem.

[+] tacone|2 years ago|reply
Incredible, I did not know that. Does anybody point out to some resources to learn more about this behavior?
[+] hgl|2 years ago|reply
Many people seem to be unenthusiastic about it because the limitation on query strings are usually large enough.

I personally like this addition, because it no longer requires all queries be shoehorned into query strings. You can use any syntax you like, be it SQL or GraphQL etc.

[+] tkiolp4|2 years ago|reply
Wouldn’t be enough to “extend” GET so that it supports a body payload as well?
[+] dragonwriter|2 years ago|reply
No, because that would make GET not-cachable by URL alone, which breaks systems that rely on the fact that it is.

A new method doesn’t break existing systems.

[+] time0ut|2 years ago|reply
It sort of does, but support is spotty. I've tried using it only to have things like MITM proxies on my customers' corporate networks drop the body. It'd be a large push to get universal support. It may be more difficult than simply adding a new method.
[+] simonw|2 years ago|reply
The only software I have seen that does this is Elasticsearch - it works with their client libraries but I'm always worried there may be proxies and suchlike which don't support it.

They support POST as a fallback.

[+] jillesvangurp|2 years ago|reply
You can actually do that already. It's one of those things where the specification is a bit loose on this. Elasticsearch is an example of a product that supports doing a GET with a body to do search. Works fine but not all http clients allow you to do this so they also support POST.

Nice discussion on HTTP GET with a body here: https://stackoverflow.com/questions/978061/http-get-with-req...

TLDR. the http 1.1 spec was a bit vague on this and allowed people to send a body but specified that servers should ignore that if they did. Later updates of the 1.1 spec removed that sentence and actually allow this. The caveat that the spec mentions that some implementations may not support it.

So an update is not needed; it's already allowed.

I tend to not get too hung up on the meaning of http verbs. I sort of lost interest in the endless debates on this years ago. I like a well designed REST API of course and I try to follow the principle of the least amount of surprise when I implement one myself. Using exotic new experimental http verbs would be surprising. Using GET this way is also a bit surprising. I actually steer clear of using PATCH as well. Just use a PUT or a POST and move on.

Adding new verbs to HTTP is redundant as far as I'm concerned. Not really against it but where does it stop? And what do we get out of it? It doesn't sound like it's worth the trouble.

[+] Makhini|2 years ago|reply
It already does.
[+] BugsJustFindMe|2 years ago|reply
> GET requests ... can't have a request body. It's not specifically banned, but it is defined as being completely meaningless

This is widely believed but false. And repeating it leads me to believe that the author is not careful enough to create new standards. They are just not defined to be meaningful, which is not the same thing.

In fact the standard says that sending a message body with a GET request should not (specifically SHOULD NOT, not MAY NOT) be done unless you have confirmed that the servers accept it, because servers are not required to accept it, but that if you are talking to a server directly that you know supports it then it's perfectly fine and within the standard.

[+] poisonborz|2 years ago|reply
As other commenters pointed out, support is spotty and it's generally a greyzone. A new verb (I'd also support "QUERY") would clarify things.
[+] akvadrako|2 years ago|reply
But it doesn't actually work in many browsers.
[+] pan69|2 years ago|reply
Another way to think about it, if you're doing REST as it seems the author of this article seems to strive for is to introduce a "search resource". You'd then POST to e.g. POST /searches with the query in the body, and on the server side a search resource is created. The server performs the search query and returns the result with a search ID. To do the same search again just do a GET /searches/ID.
[+] wizofaus|2 years ago|reply
One of the user cases listed - being able to send a large body of data to a server for it to encrypt (though it could be any sort of transformation, e.g. reformatting, encoding, format conversion, or even operations like "spell check" etc.) strongly suggests to me we don't need a new verb, but should simply redefine the expected behaviour for GET requests for when they do or don't have a body - even if it means there's a expectation and method for clients to first query servers whether they have that ability (as servers that don't support "search" will return an error if that verb is used, whereas servers, esp. proxies/load balancers etc, may well simply ignore the body if GET is used.). And to not define caching semantics seems somewhat crazy - it's bound to result in implementations inventing their own (the obvious one would be to combine some hash of the body with the URL to uniquely identify the request).
[+] Too|2 years ago|reply
By adding the new verb, it implicitly formalizes that body in GET should not be used. Previously it was allowed, although not always expected.

This may be a good thing and it could also be a bad thing if middleware starts relying on this new expectation and break old applications that previously assumed get bodies to be passed through.

They should clarify the expected behavior of GET bodies more explicit, whether it is allowed or not doesn’t really matter, as long as it is crystal clear.

[+] ThaFresh|2 years ago|reply
being from 2021, I guess this one didnt pan out
[+] dragonwriter|2 years ago|reply
Its still actively being worked (the most recent workgroup draft, and IIRC several of the internet drafts since the posted one, names it QUERY, SEARCH as a name for thr verb is probably dead) though, yes, the particular 2021 draft didn’t get adopted as anything more.
[+] cratermoon|2 years ago|reply
I'm trying to imagine an example of the authors primary use case: "a complicated data retrieval, sending lots of data but not changing the server state". Is he imagine sending something like a SQL statement SELECT with multiple WHERE and JOIN clauses using a recursive CTE?

If defining the attributes of the thing to return takes that much complexity, maybe that's a sign the endpoint is poorly designed, rather than GET query string length being insufficiently large.

[+] bastawhiz|2 years ago|reply
A great example of this today is GraphQL. Even if you disagree with the premise of GQL, you can understand how you can have complicated filtering and sorting logic, and conditional expansion of nested resources. For a nontrivial data model, you may want to select only a minimal number of fields on each nested resource. Having lots of different variants of the same endpoint to serve the same query with different shapes of output is difficult to maintain, so this makes some sense.
[+] slondr|2 years ago|reply
We actually run into the query limit problem super often where I work. User-facing search pages for very complicated data models create very complicated URLs quickly.
[+] LinuxBender|2 years ago|reply
I was under the impression that new methods could not be amended into an existing RFC by revision but would require a new major.minor version all together is that not the case? Or is this worked around with the concept of extensions and if so doesn't that mean vendors of middle boxes are not required to recognize it?
[+] mdale|2 years ago|reply
Maybe read only query getting larger than the GET length limit indicates it's post-processing the object for you and not a "cachable" resource from a key value retrieval perspective? I.e your POST'ing a read only query since an application has to process the query for your at that point ?
[+] samwillis|2 years ago|reply
If they do add this I hope they also add support to the Browser History pushState API to set the request body. You can obviously set an arbitrary JS state object, but for server rendered "html over the wire" single page apps it would be nice to be able to do a pushState that is sent to the server on refresh.
[+] politician|2 years ago|reply
I used a SEARCH verb for an REST API years ago. Granted, we only had to support clients that we wrote ourselves. Semantically, however, it made a lot of sense to include a payload in the request body describing the query.

No one else needed to know or care that it existed.

[+] phendrenad2|2 years ago|reply
Can anyone steelman this idea for me? Seems like an incredible waste of time to make this.
[+] pzlarsson|2 years ago|reply
This sounds promising as a lot of use cases are shoe horned into the current verbs. A bit surprised EVALUATE isn't discussed as a name since it would make sense both for search queries and other "get using body" scenarios.