Defining a new HTTP method: HTTP Search (2021)
httptoolkit.com
httptoolkit.com
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.
Many systems limit the length of the URL, so this is significant.
It would definitely heavily depend on the dataset you're querying... Very little value in cached search results if you're searching through time-sensitive data such as logs or other live-datasets.
Most datasets I've searched also has a concept of permissions, so person a couldn't be served the same cached result as person b... I think search can't be cached at the http level either, its too heavily dependent on the data you're searching through so you'd have to implement it in the application anyway.
the article does make a good point though: a `get` request that supports a `body` would be nice, and thats pretty much all they're arguing for with the `search` verb.
(Of course, you could instead bump the HTTP version for support of GET-with-body, but given how HTTP/2 and HTTP/3 are defined in terms of HTTP/1.1, you’d need three new versions of HTTP for a change to core verb semantics. A new verb, again, is far simpler.)
There's a reason elasticsearch accepts POST
Is it implied idempotency and the lack of a confirmation dialog when the user reloads the page?
If there was a GET-with-body http verb I'd probably use it at one point or another, but I often wonder where plain GET would start blowing up if I just used it for that.
Honestly, I think rest is a mess, and that everything should just be POST with no values in the url at all.
no, you cant. if the server requires any headers such as Authorization or Cookie, this method will fail.
And even then, they are still correct while you are not. You can copy the GET url even if it ultimately it requires authentication in a way that you can’t do it all for a POST request.
A separate format to serialize a request spec is a good idea, sure, but it is a distinctly different thing than the URI of the resource referenced by the request.
Forget about what acronyms stand for. The thing that hyperlinks point to and you can type in your browser bar is called the URL or the link.
And the point is that being able to specify a verb and headers in a link would be super useful in certain situations.
Continue to call it a URL or URI and just change the "R" in those from Resource to Request, semantics problem solved. Or invent a new URA where "A" stands for "action" and it's a valid hyperlink. The naming of it is the least important part here.
HTTP is a two-way messaging protocol. What's being talked about here is the capabilities in hyperlinks. Totally different.
HTTP, at its heart, is a way to compose an action from a verb and a noun - such as "get this", or "update that". The request method, or verb, is intertwined with the URI, or resource, the noun - together, they form the action the user agent intends to carry out. "GET /foo" is entirely distinct from "POST /foo", and there are lots of considerations why it has been implemented like that. I cannot recommend reading the spec (or letting ChatGPT summarise it for you) enough, it will really make more sense.
Having said all that, I know what situations you are referring to - say, issuing a PATCH request with an HTML form, or circumventing some redirect bug with a POST request. Still, all of those problems hint at some other, more general issue, and solving such inconvenience would come at the price of a completely broken HTTP specification. Protocols like email, or HTTP, have only been around for so long because they were designed elegantly and carefully. Let's not break that for convenience' sake :)
None of this suggestion is about incorporating all of HTTP's functionality. It's just the situations that you say you know I'm referring to -- verbs, things like authorization headers, a POST payload.
Expanding the functionality of hyperlinks wouldn't break anything about HTTP. It would just allow more requests to be defined in a single line of text (a hyperlink), rather than requiring lines of JavaScript to define. The browser (or cURL or whatnot) would convert the link to the actual HTTP request. Zero changes to HTTP.
What you’re looking for is a browser extension, not a haphazard URI change.
https+rpc:||news.ycombinator.com|reply?id=36096485&goto=item%3Fid%3D36095032%2336096485#method=PUT#H-Accept=text/html
with | instead of / to workaround this site encoding
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.
https://httpwg.org/http-extensions/draft-ietf-httpbis-safe-m...
"POST" has come to imply a "write" operation, and mixing up the the reads and writes of a system leads to cognitive dissonance.
Not idempotent: POST
idempotent/not safe: PUT (body matters), DELETE (no body)
safe: QUERY (body matters)/GET (no body)
That’s why QUERY is needed. POST is not a good substitute.
Could be used for e.g. SQL over HTTP
https://www.ietf.org/archive/id/draft-ietf-httpbis-safe-meth...
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.
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
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.
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.
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.
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.
Going to have to review my REST APIs to make sure that’s not a problem.
That being said, I don’t see this feature being particularly beneficial either. Only the caches which observed the request could know to purge the cache. So you can’t actually rely on it for cache invalidation.
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.
(paragraph starting “Although request message framing is independent of the method used”)
In any case we are talking about updating servers.
They support POST as a fallback.
A new method doesn’t break existing systems.
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.
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.
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.
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.
GQL solves this problem in a particular way, but even folks who don't turn to GQL still have this problem.
If you aren't in those spaces it probably seems unnecessary.
No one else needed to know or care that it existed.
As I said, this is totally naive. Is there some obvious reason why this is a terrible idea, or not really possible?
From the very first line in the RFC[1]:
"The Hypertext Transfer Protocol (HTTP) is a stateless application- level protocol for distributed, collaborative, hypertext information systems."
Which is why you need to send a header every time you make a request with authorization data.
Given that: no, stateful methods like OPEN/CLOSE would not fit at all with how HTTP is designed to work.
But, adding other methods than GET to the address bar in browsers is an interesting idea. It'd affect such a small percent of people it'd most likely be a net time sink than time saver, though.
Most servers will reject URLs after a certain size, 4-8KB.
Overall, I'm not necessarily inherently against new HTTP methods. If equipment that is supposed to be transparent to HTTP isn't, should be solved elsewhere, not by a new HTTP method.
It's better to fail on the ones that slip through the cracks than to leak data. And the failure alerts people that updates are needed here.
So, GET URLs with base64 encoded data is definitely ugly, but at least you can save them and share them easily.