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.
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.
> 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.
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.
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.
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.
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.
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.
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.
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.
> 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.
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.
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.
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.
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.
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.
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.
> 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.
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.
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).
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.
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.
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.
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.
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.
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?
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 ?
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.
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.
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.
[+] [-] asattarmd|2 years ago|reply
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
[+] [-] phailhaus|2 years ago|reply
[+] [-] deepzn|2 years ago|reply
[+] [-] BugsJustFindMe|2 years ago|reply
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
[+] [-] imnotjames|2 years ago|reply
[+] [-] candiddevmike|2 years ago|reply
[+] [-] 2h|2 years ago|reply
no, you cant. if the server requires any headers such as Authorization or Cookie, this method will fail.
[+] [-] montroser|2 years ago|reply
[+] [-] dragonwriter|2 years ago|reply
https://httpwg.org/http-extensions/draft-ietf-httpbis-safe-m...
[+] [-] ZiiS|2 years ago|reply
[+] [-] wilg|2 years ago|reply
[+] [-] Raqbit|2 years ago|reply
[+] [-] Spivak|2 years ago|reply
https://www.ietf.org/archive/id/draft-ietf-httpbis-safe-meth...
[+] [-] mlhpdx|2 years ago|reply
[+] [-] yashap|2 years ago|reply
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
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
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
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
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
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
Going to have to review my REST APIs to make sure that’s not a problem.
[+] [-] tacone|2 years ago|reply
[+] [-] hgl|2 years ago|reply
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
[+] [-] dragonwriter|2 years ago|reply
A new method doesn’t break existing systems.
[+] [-] time0ut|2 years ago|reply
[+] [-] simonw|2 years ago|reply
They support POST as a fallback.
[+] [-] jillesvangurp|2 years ago|reply
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
[+] [-] BugsJustFindMe|2 years ago|reply
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
[+] [-] akvadrako|2 years ago|reply
[+] [-] pan69|2 years ago|reply
[+] [-] wizofaus|2 years ago|reply
[+] [-] Too|2 years ago|reply
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
[+] [-] dragonwriter|2 years ago|reply
[+] [-] cratermoon|2 years ago|reply
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
[+] [-] slondr|2 years ago|reply
[+] [-] LinuxBender|2 years ago|reply
[+] [-] mdale|2 years ago|reply
[+] [-] samwillis|2 years ago|reply
[+] [-] politician|2 years ago|reply
No one else needed to know or care that it existed.
[+] [-] phendrenad2|2 years ago|reply
[+] [-] pzlarsson|2 years ago|reply