In case you're not sure what the difference between GET
and POST
in HTTP are (or what that sentence even means), here is a great post from today:
It got me thinking that there are definitely situations where folks hack on different methods to create the desired outcome. Sometimes GET
is used alongside a "url param" password of sorts in contexts like one-click actions from an email (for unsubscribing or otherwise).
I also notice that, for example, Algolia uses a POST
request for searches where I would expect a GET
request. I think this is for mild performance improvements, or simply for consistency due to the fact that some of their requests probably should be triggered via POST
.
Anyway, what are your thoughts about when to use the "wrong" method, or if this is ever advisable?
Top comments (30)
A one-time action URL as a
GET
request does break the idempotency property, but what else are you going to do?At the end of the day the pragmatic solution is best. Solve the problem while introducing as few side problems as possible. And keep it simple -- that's my general philosophy.
The real rabbit hole of the HTTP methods debate is once you get into the semantics of
PUT
/DELETE
and frankly I don't see the advantage.GET
andPOST
have the simplest semantics and you can build APIs that are super clear, pragmatic and easy to use with just those two methods, occasionally bending the rules when it's helpful but keeping things as predictable as possible."what else are you going to do"- The way to do it inline with HTTP standards is that the email link sends the user to a form where they click "confirm email" and that form sends a patch request. If you instead alter the resource in email GET link the action might be triggered without user interaction, "e.g. by a malware scanner, link previewer, or cache primer". To what degree this is actually an issue I'm not sure because many apis use GET regardless and it seems to work enough for them to continue doing it.
Why you should use standard HTTP methods when designing REST APIs
Suhas Chatekar ・ Feb 23 '17 ・ 7 min read
That article doesn't give a strong argument against ONLY using get/post IMO. His main point is to maintain idempotency, but you don't need all the extra verbs beyond get and post to do that.
Misuse of what exactly? A set of poorly defined methods designed in a vaccuum by people who clearly didn't consider UI design nor proper web architecture and long before modern web apps were even considered.
The whole web stack is a giant workaround. Do whatever you want with HTTPs methods -- provided it works. Nobody can fairly judge you as doing anything wrong.
While I appreciate the rage
is patent nonsense. It was designed on the fly as the World Wide Web took off in the 90s - as far from a vacuum as you could get. As is
The 'web stack' is trying (or at least was trying) to leverage the incontestable success of the WWW as distributed hypertext (in the 90s) into distributed systems architecture. That was the whole point of REST. Yes it's a kludge - all the great and useful things are kludges. But it's a kludge built over the most successful, open and transparent transport protocol of all time. Most of the really workaround solutions - things like SOAP and RPC over XML - are pretty much toast now, although everyone keeps telling me that RPC is cool again.
... sure, although they may fairly judge you as doing something unexpected.
“The whole web stack is a giant workaround.” Yeah baby! That how you say it!
Setting REST aside for a moment, the main issue with not using
GET
for read only requests is that you forego HTTP caching, which is a huge deal in many cases.I'm definitely pro trying to stick to the standard but also I think it's okay to bend it if necessary.
I don't agree with people saying "fudge it" on principle, just because it seems that they don't want to learn HTTP in the first place :D
I think that REST is not perfectly suitable for contemporary applications, which are simply too complicated for it to handle gracefully. The simplest example I can give is a
/login
, where no conventional method works (you're notGET
ting information, notPOST
ing norPUT
ting some payload [and dear God don't useDELETE
]). The ultimate solution would be a combination of REST and RPC of some sort, in my mind.Lately I've been getting into GraphQL and I gotta say I fell in love with it, as I feel it is the replacement of REST I've looked for. They opted to put the whole query in a POST request (be it GET, POST, PUT or DELETE equivalent), but in a nice structure that is easy to follow and manage.
Actually the more I build complex apis, the more It messes my head around to stick with REST because of consistency issues.
For example, I would have a route to display all the shoes in a shoe store in GET
/api/shoe
, but getting the users liked shoes would be used through Post/api/shoe/liked
because I authenticate the user with a JWT and I prefer to use a POST parameter because of the limit in GET queries and the fact post parameters are less easy to sniff than get... But this would work fine in GET because my tokens are not so long and my urls quite short but I do this to prevent any issues.Also, it has for a moment make me wonder how complex it is to stick with only GET,POST,PUT,DELETE. An example is when you want to provide an "undo" feature.
Say you can trash a comment, or remove it permanently. Trashing would be seen as the equivalent of soft deleting, so why not use DELETE. But then you have the actual deletion, or maybe named destruction. Will you use DELETE to do this? Then the classic REST schema does not work anymore.
I feel like you, today REST gets less and less optimal for complex apps, GraphQL seems to be more suited.
I guess it depends on what you're doing. Logic I use for determining things like this:
GET
,PUT
,DELETE
, orPATCH
in my experience.GET
request.PUT
request unless some other request has specific semantics that fit better.POST
request, probably with headers to prevent caching.The thing is, in reality, if your request doesn't actually fit the first three cases, there arguably isn't a HTTP method that does exactly what you want, and it just makes the most sense to use the de-facto standard catch-all method.
Hmmm.. Building good REST api is tricky and building API for internal or external API can be a nightmare.
I find that if they are using either OpenAPI specifications and related tools or Postman.
They are serious in API development work.
Lastly having example like Auth0, Twilio or Salesforce is really a good leader to copy their design concepts.
I had used non-standard methods like
PUT
andFETCH
in a REST API app I'd created as a side-project some time back.But now that I think retrospectively, its not really needed. You can simply use one POST method with "action" or something as a parameter corresponding to the REST action you want (such as
create
,delete
,update
orinsert
).Probably the main technical reason why I use the "wrong" method (POST) for read-only queries is because of all the layers of caching that I have to bust with GET requests. My internal APIs are typically for live data, so caching is not desirable. I've done the efforts before to use GET because it was the "right way". But in the end it was a lot of yak shaving that I could have avoided just by using POST.
Whatever people later appropriate HTTP methods to mean (e.g. REST), they already have pretty well-defined behaviors to most web servers. For example, GET requests also have a limited amount of data they can send (whatever length URL the web server will accept). And URLs are typically logged (also undesirable in many cases). So rather than ideologically trying to match up what someone says I should do, I try to match up the actual functionality with my needs.
That's also why I arrived at using request/reply messaging instead of REST. And using commands and queries instead of GraphQL. These allow me to focus on what the user is trying to learn and accomplish rather than being an exercise in munging data.
Like anything else, there are the die-hard theorists who say never break the pattern. But that isn't a good enough reason to listen.
A good reason to do things "correctly" is that your tooling will expect you to do it correctly. End users, if it's a public API or even public inside your company, will expect you to do it correctly. If you do it in a non-standard way, it may cause you to have to write additional documentation, which is an expense.
You have to weigh out each situation. When making an API, I'd stick to the convention unless I had a particularly good reason not to. One example is the GET with a token for password reset. Just obviously be aware of the implications - e.g. query params expose data. Make sure it's not sensitive or short-lived.
And writing a prototype isn't a good enough reason to skip convention. Many a production app is still running its prototype code.
I feel dirty when I have to admit this, but doing a route that should be a GET via POST because the URL and the query parameters could become to long. We had a long discussion about this and were looking at how others handled. We found out Google basically said they did the same thing to get around the limits, so we went forward with the dirty feeling.