DEV Community

Ben Halpern
Ben Halpern

Posted on

How do you feel about the "misuse" of HTTP methods?

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)

Collapse
 
marek profile image
Marek Zaluski

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 and POST 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.

Collapse
 
dashbarkhuss profile image
Dashiell Bark-Huss • Edited

"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.

Collapse
 
nektro profile image
Meghan (she/her)
Collapse
 
chadtiffin profile image
Chad Tiffin • Edited

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.

Collapse
 
mortoray profile image
edA‑qa mort‑ora‑y

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.

Collapse
 
gypsydave5 profile image
David Wickes

While I appreciate the rage

designed in a vacuum

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 whole web stack is a giant workaround

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.

Nobody can fairly judge you as doing anything wrong.

... sure, although they may fairly judge you as doing something unexpected.

Collapse
 
tonyorozcor profile image
Tony Orozco

“The whole web stack is a giant workaround.” Yeah baby! That how you say it!

Collapse
 
rhymes profile image
rhymes

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

Collapse
 
dorshinar profile image
Dor Shinar • Edited

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 not GETting information, not POSTing nor PUTting some payload [and dear God don't use DELETE]). 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.

Collapse
 
anwar_nairi profile image
Anwar • Edited

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.

Collapse
 
ahferroin7 profile image
Austin S. Hemmelgarn

I guess it depends on what you're doing. Logic I use for determining things like this:

  • If there's a method that exactly matches the required semantics, use it. Usually, this translates to GET, PUT, DELETE, or PATCH in my experience.
  • If it doesn't modify server-side state and is cachable, it's a GET request.
  • If it does modify server-side state, but is idempotent, it's a PUT request unless some other request has specific semantics that fit better.
  • Otherwise, it's a 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.

Collapse
 
steelwolf180 profile image
Max Ong Zong Bao

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.

Collapse
 
prahladyeri profile image
Prahlad Yeri • Edited

I had used non-standard methods like PUT and FETCH 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 or insert).

Collapse
 
kspeakman profile image
Kasey Speakman • Edited

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.

Collapse
 
jdforsythe profile image
Jeremy Forsythe

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.

Collapse
 
jbarngr profile image
Jeremy Barngrover

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.

Collapse
 
wolfhoundjesse profile image
Jesse M. Holmes

When I was building software for the Army, we learned that certain request methods were blocked. For us, it was just one more drop in the it is what it is bucket.

Recently I've discovered that some of our applications return a failed authentication response as a 200 OK along with a validation messages object that says exactly the opposite.

It's my preference to be bothered by this type of thing. People meet, discuss, and make decisions about these things, so who am I to say, "Thanks for the suggestion, but I'll be going my own way."

Sometimes, though, it is what it is.

Collapse
 
waynejwerner profile image
Wayne Werner

If I recall from Algolia I think there's also side effects from your searches, so POST would make more sense there. I have mixed feelings about it I guess. Most of the time I think it's a good idea to stick to GET only returning stuff, and POST when you want to change the state of something on server side. Oh, yeah, and when you GET stuff then your params show up in your search history, so if you're including things like auth tokens or (gasp) password, that's very much not a good idea.

Collapse
 
karlredman profile image
Karl N. Redman

I don't care. Not at all.

What I mean by saying this is that the problem, in this situation, dictates the solution. @nielsoftware seems to have a great workflow while @dorshinar has a great point relative to API. The commonality seems to be scope and scale.

This concept irks me. Scope and Scale are restrictions (constructs) from an engineering point of view. Forcing a different paradigm among constructs is a basic programming no-no. I'd say the issue is a) under engineered and is a one-off b) under engineered and perceived to be a one-off c) over engineered and has too many options d) lacks clarity in it's definition.

my 2 cents

Collapse
 
gypsydave5 profile image
David Wickes

I don't mind people using the "wrong" method.

What DRIVES ME FREAKING INSANE is when they do this but tell me it's a "REST API".

Collapse
 
xowap profile image
Rémy 🤖

I don't give a fuck about methods purity, but there is a few properties to follow

  • What goes in GET parameters must be inconsequential (do not trigger any write)
  • Secrets are better in POST (as POST body are not usually logged nor visible)
  • Post friends like PUT and PATCH can have meaning for your app
  • Also GET and POST get cached differently and that's an important property as well