10 ms·
Request bodies in GET requests
- GordonS 5y agoIt's always bugged me having to use POST for complex query requests that have "outgrown" URL parameters. Had no idea a new QUERY verb was in the works - that sounds ideal.
- dylan604 5y agoThis was the first I had heard of Query as well, but admittedly I don't pay too close attention to those discussions.
- Waterluvian 5y agoSame. Also I (foolishly) perceived the spec as being rather stable and was not expecting a whole new verb.
- dylan604 5y agoThere's definitely a lot of misunderstood uses of the verbs, and I've maybe read about them one only a couple of times long long ago. I know POST gets bastardized a lot in attempts to avoid query strings attached to the end of GETs. Lots of people promoting that in tutorials/blogs/etc
- treve 5y agoQUERY seems to be on the path to standization, but using POST if other methods don't fit is/was the right way to do this! Both PATCH and QUERY are newer and they are really specializations of what people used to use POST for.
- throwawayboise 5y agoI have had to bastardize POST in a situation where I had to support an HTTP client that only implemented GET and POST. So the desired action, e.g. DELETE, was included in the POST data.
- dillondoyle 5y agogenuinely curious. why? Does it make a big difference in your code or user experience?
- isbvhodnvemrwvn 5y agoCaching gets rather tricky.
- dylan604 5y agoMaybe because caching POST data is just an odd way of doing things?
- nrmitchi 5y agoYou often want to cache results of complex queries. If these are POST, you find yourself trying to conditionally cache POST requests, which opens up a whole new class of caching bugs.
- NavinF 5y agoIf the queries are that long (over 2k-ish bytes), wouldn’t you wanna write a query file with POST and then execute it by name with a GET?
- wtetzner 5y agoThen you need to build infrastructure for storing queries. Depending in the specifics of the project, that may or may not be OK.
- dastbe 5y agowhile that could be preferred, here's some reasons why it may not be 1. pre-existing behavior. maybe queries have only started getting big enough to where this mattered, but all of our existing clients communicate the original way and won't migrate 2. more complex behavior on clients and services as you've now introduced a new stateful resource between client and service. should clients store query ids, or does the service handle idempotency? what db does the service use to store queries? how do we limit stored queries? do clients have to manage number of queries stored? does the service?
- fxleach 5y agoWhy does it bug you?
- toyg 5y agoThe problem with "exotic" verbs is that proxies in the middle will often misbehave when faced with them. There is some old network infrastructure out there.
- wizzwizz4 5y agoWith HTTPS, that doesn't matter.
- mh- 5y agonot really. there are plenty of middleboxes deployed by IT departments that happily mess with HTTPS traffic, too.
- tedunangst 5y agoThere are intercepting https proxies.
- jrockway 5y agoThe proxies in question strip HTTPS, and re-encrypt with a certificate your IT department installed on your device.
- UglyToad 5y agoI really, really, hate REST prescriptivism. I'm going to return 200 from POSTs and want to use request bodies for GET requests to do filtering. We may as well use POST for updates. REST doesn't work for my use-case or probably most use-cases but people seem to treat it like an article of faith even when it forces a completely bass-ackwards design. SOAP was the pinnacle of API design.
- gls2ro 5y agoYou can do that (adding body to GET) but you might generate some restrictions for using the cire. Example from the article: > When working with HTTP, there’s servers but also load balancers, proxies, browsers and other clients that all need to work together. The behavior isn’t just undefined server-side, a load balancer might choose to silently drop bodies or throw errors. There’s many real-world examples of this. fetch() for example will throw an error.
- UglyToad 5y agoSorry I wasn't clear. The lack of defined behaviour for bodies in GET is an example of harms arising from REST obsession. It's clearly a useful thing but because it goes against the intended design it's treated as a bad idea. It just feels like REST discussions are where the strongest divide between pragmatism and bikeshedding occur.
- cryptonector 5y agoWhile REST obsession is a thing, the "lack of defined behaviour for bodies in GET" arises from the fact that it's defined to not have a request body, therefore there exists a lot of code that assumes it has no request body and acts accordingly, leading to interoperability problems. You have to separate HTTP, the spec, from REST the philosophy. REST says you should use HTTP status codes. HTTP doesn't obligate you to use the full range of its status codes -- you can code up a resource that always returns 200 for POSTs, and that's fine as far as HTTP goes, and not as far as REST goes.
- chrsig 5y agoI get so exhausted listening to people talk about http semantics, and arguing about the restfulness of different approaches. From an implementation point of view, the difference between a POST, GET, and QUERY with a body is...trivial. I look forward to QUERY because it'll finally stop arguing about having to send a body on GET, or do a POST for something like a search. It's gotten to the point where it all feels like naval gazing to me. I'd rather talk about what the api does rather than how amazingly restful it is.
- dylan604 5y agoAt the end of the day, I don't care. If the API I am talking to says they respond to certain information sent via specific method, that's how I send it. Yes, we could argue till the cows come home about levels of appropriateness, but I've got better things to do with that time. Like process the data I just received from GET request sent with a body!
- CodesInChaos 5y agoI think "REST" was primarily successful because people wanted a simple json-webapi, not because of its fancier principles.
- hnfong 5y agoI thought "REST" was primarily successful at first because it was a reaction to the overblown XML mess in the early 2000s (that's the "X" in XHR, even though nobody uses it for that any more). I never understood why it became dogmatic though. Arguing for practicality over dogma seems like a losing battle, even in this industry where people are supposed to be relatively practical. I guess that's human nature :-/
- polishdude20 5y agoExactly. If I need to access some api, I'll just read their docs on which methods they want you to use. I never go in thinking "oh if there's a get request for this resource, there must be a post request for this resource like this".
- bruce511 5y agoStandards are nice and all, but I've implemented a generic Web-client library and had to support payloads with all HTTP Verbs, because, well, some servers require it. Clients of a service seldom get to meaningfully complain - use the service, don't use the service, whatever... So whatever the server wants, the server gets... Although ironically I've also implemented servers and Gorton all kinds of complaining from clients - it's too hard to set a cookie, or header, can't we put tokens inside the JSON etc...
- hyperhopper 5y agoYeah, nobody is saying start using QUERY today for all your requests, it's a suggestion to design new apis with more semantic verbs that follow the spec.
- sseagull 5y agoI took a deepish dive into these kinds of issues. My interpretation is that no one uses REST properly (ie, HATEOAS). Fielding has even said so - if you aren’t designing something as big as HTTP itself, then “true” REST isn’t for you. Now there’s this thing called REST that we all commonly understand and debate over. And I have run into so many issues that I basically abandoned calling it REST and now just call it an API. And somehow it still all works just as well :)
- Osiris 5y agoYeah I tend to refer to them as HTTP APIs.
- egeozcan 5y agoUse GET for everything that can be cached and repeated without side-effects, and POST for everything else. You can delete the rest of the spec and clients can connect without head-aches but only if you can put up with the fanatics in your team trying to trace every bug to not following rest, in the rare case giving you no options other than trying patch after patch to make everything rest-compliant.
- hakre 5y ago> Use GET for everything that can be cached and repeated without side-effects As long as HTTP is concerned (which must not be specifically REST), HEAD needs to be supported next to GET, too.
- nojs 5y ago> Use GET for everything that can be cached and repeated without side-effects *except when the query string is too big, then use POST
- shroompasta 5y agoTrue. I have personally gone off the deep end and started writing 200, 400, and 500 for all my status codes instead of the specific 2xx, 4xx, 5xx ones. If details of an error response need to be mentioned, it will be in the error response body. My motivation came from GraphQL as it responds everything with 200s, and so far it has been humming along fine. True REST are more guidelines if anything.
- yob22 5y ago
- SahAssar 5y agoThe first mention of QUERY should probably point to https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-safe-method-w-body-02 https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-saf... instead of https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-semantics#section-9.3.1 https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-sem... I was a bit confused by that at first
- cryptonector 5y agoMe too. I think it's just an error by the author.
- treve 5y agoIt was! I'm fixing this
- kevmo314 5y agoAn interviewer once asked me what the difference between GET and POST were. My answer was along the lines of "well technically just four letters in the header but they're used differently" and the interviewer was absolutely adamant that I was wrong and that there was some fundamental difference between GET and POST requests to the point that I tried numerous times to steer it back towards how they're used. Eventually I gave up and just ended the interview.
- freedomben 5y agoI hate that. For some reason being the interviewer fills people with an unfounded confidence in their own knowledge. Some act like they're infallible in interviews. The result is that as a candidate you have to avoid harming their egos but at the same time don't contradict them. It can be like walking on egg shells. Last time I interviewed I pushed back but in a "are you sure? can we look it up?" kind of way and that seemed most palatable to them.
- thaumasiotes 5y agoThe name of the request is the only difference from the perspective of HTTP. But it's definitely worth mentioning that POST requests trigger a bunch of browser safety features that aren't triggered by GETs.
- stickfigure 5y agoHTTP doesn't assume the existence of a web browser...
- wanderer_ 5y agoTrue, but your garden-variety command-line utility might not be able to send a POST (like wget, but apparently curl can). Both of these concerns are valid and need to be taken together. GET can be run just like a normal URL and thus is more versatile, but as you probably understand, less secure.
- abhishekjha 5y ago
- jicea 5y agoI’ve to build a cli HTTP client in Java and went with OkHttp [1], as it was widely used on Android. I’ve to add support for GET requests with a body but I wasn’t able to do it with OkHttp. The library was rather opinionated and you couldn’t add a body to a request body back then [2]. I was rather surprised, because I thought HTTP specs allowed it, while discouraging; so an HTTP library should allow this kind of usage. I went back to Apache HTTPComponents, while less fancy than OkHttp but also less opinionated, and was able to complete my client. Things may have changed, it was a few years ago. [1] https://github.com/square/okhttp https://github.com/square/okhttp [2] https://github.com/square/okhttp/issues/5803 https://github.com/square/okhttp/issues/5803 [3] https://hc.apache.org/ https://hc.apache.org/
- sk5t 5y agoYes, OkHttp is somewhat opinionated. You probably shouldn't include an entity body with a GET request unless you really know what you're doing. I wouldn't recommend it anyhow. Years of tradition make this a risky choice.
- cryptonector 5y agoHTTP specifically says that GET has zero-length (no) request body.
- balls187 5y agoPut me in the column of being an ardent standards supporter. I really don't like buying a[n] (HDMI|USB|Lightning) cable and then finding out it's not standards compliant, so my (PS5|PC|Phone) doesn't work. I'm old enough to remember Web-development with Internet Explorer, and so old, I remember cross platform C++ development using Visual C++.
- ranguna 5y agoYour comment is a shining light in this dark comment section, thank you.
- dang 5y agoOngoing current thread: Upcoming new HTTP QUERY method - https://news.ycombinator.com/item?id=30153995 https://news.ycombinator.com/item?id=30153995 - Jan 2022 (52 comments) Recent: IETF: The HTTP Query Method ( Draft) - https://news.ycombinator.com/item?id=29794838 https://news.ycombinator.com/item?id=29794838 - Jan 2022 (125 comments)
- lhnz 5y agoThis brings back memories. I once failed an interview because an interviewer asked me how a certain API could be implemented and I suggested that you could send a body with a GET request. My thinking at the time was that, even though unusual, Elasticsearch does this (2016: https://github.com/elastic/elasticsearch/issues/16024#issuecomment-172491501 https://github.com/elastic/elasticsearch/issues/16024#issuec...) and it might be easier to cache than POST but I could tell that the interviewer wasn't happy with my reponse. Glad that a QUERY method will be provided instead, and I learnt my lesson about giving against-the-grain responses to interviewers.
- gautamdivgi 5y agoThe QUERY method is definitely the way to go. GET with a body is iffy. If you owned the entire stack it might be doable. But once you don't have control of the many http proxies and firewalls that a GET with a body has to travel then it becomes a problem. I think the RFC does not explicitly define the behavior of GET with a body. So, proxies or firewalls can just drop the message and be completely HTTP compliant. Not passing judgement - you may have very well qualified your statement. But having dealt with the above issue some years back (as in being the person on the debugging run) I do sympathize with the unhappiness. :)
- lhnz 5y agoYeah, your point about needing to own the entire stack in this case makes perfect sense, and to be honest, I didn't qualify what I said well at all at the time. When I left the interview I had that sense of "damn, why did I say something so strange with no explanation of where I'd seen this or argument against it". There could have been a conversation about it, but my response just made the interviewer tick the 'no' box.
- cema 5y agoWell if that's the case then the interview process was not well put together.
- 5y ago
- ogazitt 5y agoSeems like the HTTP/2 protocol has been baked for so long, that whatever new methods are added, adoption will be very slow and only a small fraction of web APIs will expose those methods. In other words, aside from <1% of developers, no one will care. Also, graphQL seems to address many of the issues that manifest in the current form of GET. My bet will be that graphQL gets adopted more widely (and faster) than a new QUERY method.
- cryptonector 5y agoHTTP specifically leaves the set of methods open to extension.
- dc-programmer 5y agoI disagree with many of the posters here saying that the difference between GET and POST is irrelevant or a social construct or something like that. Intermediate proxies and browsers apply different caching rules to GET vs POST responses. This can have huge performance and security implications. Along the lines of security, browsers impose stricter security mechanisms on POST requests. Cross site POST calls require a CORS pre-flight options request, and the response of this request is scrutinized. Choosing GET vs POST can be the differences between having CSRF protections and having none. Sometimes I feel that some of the opinions here are not very useful without the context of the environments in which they are deployed. A few weeks ago I saw someone wrote that logging is an anti-pattern because correct code doesn’t need it. That may work for a small project, just like using fat GET requests may be fine for most projects. But when you are building complex software at scale, the importance of following the normal practices becomes very evident
- andirk 5y ago> The [query] spec also makes it cachable. This, or having a body on a GET request, is the best option due to caching implications, of which said implications are often opinionated (not according to a spec) along the entire path of request/response.
- luhn 5y ago> Cross site POST calls require a CORS pre-flight options request, and the response of this request is scrutinized. Not in all cases. Certain POST requests count as "simple" requests and no preflight check is performed. For example, a POST with application/x-www-form-urlencoded data and no extra headers doesn't need a preflight, because you could make an equivalent request with an HTML form. https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simpl...
- deleted 5y ago[deleted]
- capableweb 5y agoAnd continuing on that note, non-simple cross-origin GET requests initiated via JS also requires a pre-flight OPTIONS request (actually any non-simple HTTP request would require this). See https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simpl...
- morelish 5y agoFor REST api design I've always kind of been pissed that GET doesn't come with a body. (Yeah I know you can do it anyway.) Just because encoding complicated parameters into the URL is pretty sucky at times. I suppose a QUERY would really solve the problem. Maybe it's the best compromise.
- unixbane 5y ago>use QUERY instead because it's undefined Nobody uses QUERY and it will thus have surprising consequences in no different amount than GET with a request. Firewalls will block you for "hacking". It's absolutely insane and idiotic that this is even a question. HTTP, which is a protocol that has no stated purpose, could have had no method at all and it would have made no difference. They could have just shoved whatever caching concern bullshit rationale which isn't sound either into more header lines. HTTP is a turing tarpit for protocols. Please close your websites, the users hate it and so do the engineers.
- csours 5y agoIs there a name for a pattern where base64 encoded JSON is used as the query string to a GET request?
- kazinator 5y agoIf it's a piece of base64 that a random web visitor uploaded and then another one picked up such that it was activated as a request in their browser, the name which applies is: "cross site scripting attack".
- vsnf 5y agoIf i understand the common critique from the comments here it's that GET with a body, while not bad on its face, is nevertheless discouraged because you're gambling with any number of intermediate systems that may strip the body from the request. But what about DELETE with body? It's similarly unspecified, but it seems to me to be of a different breed. The point made about GET is that, under the assumption of a theoretically idempotent and immutable operation, various caching systems can kick in and serve a request from any potential world-wide server. But a DELETE is by nature a mutating event, and will always need to be directed to some kind of principal server, meaning it should probably escape the caching the same way POST requests do. Is it just as much a gamble to do DELETE with body as it is GET with body?
- dragonwriter 5y ago> If i understand the common critique from the comments here it's that GET with a body, while not bad on its face, is nevertheless discouraged because you're gambling with any number of intermediate systems that may strip the body from the request. That's a problem. > But what about DELETE with body? It's similarly unspecified, And faces the same risk that intermediate systems might reject it or strip the body, called out in RFC 7231. > But a DELETE is by nature a mutating event, DELETE is, more to the point, and despite being idempotent, expressly not cacheable, so there is no risk of getting served the wrong cached response based on the body being stripped. But, aside from the request not fitting the defined semantics of what DELETE means, you still have the risk of rejection or the request having the body stripped.