10

OK, I know already all the reasons on paper why I should not use a HTTP GET when making a RESTful call to update the state of something on the server. Thus returning possibly different data each time. And I know this is wrong for the following 'on paper' reasons:

  • HTTP GET calls should be idempotent
  • N > 0 calls should always GET the same data back
  • Violates HTTP spec
  • HTTP GET call is typically read-only

And I am sure there are more reasons. But I need a concrete simple example for justification other than "Well, that violates the HTTP Spec!". ...or at least I am hoping for one. I have also already read the following which are more along the lines of the list above: Does it violate the RESTful when I write stuff to the server on a GET call? & HTTP POST with URL query parameters -- good idea or not?

For example, can someone justify the above and why it is wrong/bad practice/incorrect to use a HTTP GET say with the following RESTful call

"MyRESTService/GetCurrentRecords?UpdateRecordID=5&AddToTotalAmount=10"

I know it's wrong, but hopefully it will help provide an example to answer my original question. So the above would update recordID = 5 with AddToTotalAmount = 10 and then return the updated records. I know a POST should be used, but let's say I did use a GET.

How exactly and to answer my question does or can this cause an actual problem? Other than all the violations from the above bullet list, how can using a HTTP GET to do the above cause some real issue? Too many times I come into a scenario where I can justify things with "Because the doc said so", but I need justification and a better understanding on this one.

Thanks!

Community
  • 1
  • 1
atconway
  • 20,624
  • 30
  • 159
  • 229
  • 2
    It doesn't cause real problems if you're OK with the fact that your updating query may be fired again at any time (cache query, bot, etc.). My conclusion is that if a guy of my team, knowing the problem because he's read the SO questions you linked to, uses GET for an updating query, then I should consider a disciplinary action. – Denys Séguret May 09 '12 at 15:22
  • 2
    what would you say if someone wrote method named GetSomething(id,value) in some third party API and you have to use it ? – Milan Svitlica May 09 '12 at 15:23
  • 1
    That's a bit like asking why a function called "GetSomeResource" cannot in fact set the resource. Technically, you can do it but then good luck maintaining the API and good luck to anyone who has to use it. – laurent May 31 '12 at 11:18
  • 1
    Arrggg, don't get fixated on the example code or naming I used. It's like I stated before: *"It was a pseudocode made up example of an improper REST call to help extract answers to my question"*. The bigger picture question here (which the post by the proper provided answer understood) was why is it bad practice to make GET calls that do updates in RESTful calls. – atconway May 31 '12 at 19:36

5 Answers5

22

The practical case where you will have a problem is that the HTTP GET is often retried in the event of a failure by the HTTP implementation. So you can in real life get situations where the same GET is received multiple times by the server. If your update is idempotent (which yours is), then there will be no problem, but if it's not idempotent (like adding some value to an amount for example), then you could get multiple (undesired) updates.

HTTP POST is never retried, so you would never have this problem.

Francis Upton IV
  • 19,322
  • 3
  • 53
  • 57
  • Yes correct - I was trying to make a call that was *not* idempotent and I guess I had one that still was. I just updated my example with 'AddToTotalAmount=10' to make the call not idempotent. – atconway May 09 '12 at 15:35
  • Is the re-trying of the GET call the only main pitfall you can see? Great one though and still justification enough, just wondering if there are any more reasons. – atconway May 09 '12 at 15:38
  • 1
    Yes, that's really the only one as far as I know. If you look at the HTTP implementations that's really the only difference between a GET and the other HTTP requests. – Francis Upton IV May 09 '12 at 15:46
  • One last question - is the GET *automatically* retried on failure (like built in functionality), or you were just saying in *practice* developers often work in a programatic re-try? – atconway May 10 '12 at 13:32
  • 2
    It depends on the HTTP client implementation. I wrote the Oakland Software implementation and it automatically retried. I think the Sun Java one and the Apache HTTPClient do as well. It's not something the developers worry about. – Francis Upton IV May 10 '12 at 15:42
5

If some form of search engine spiders your site it could change your data unintentionally.

This happened in the past with Google's Desktop Search that caused people to lose data because people had implemented delete operations as GETs.

Darrel Miller
  • 139,164
  • 32
  • 194
  • 243
1

Here is an important reason that GETs should be idempotent and not be used for updating state on the server in regards to Cross Site Request Forgery Attacks. From the book: Professional ASP.NET MVC 3

Idempotent GETs
Big word, for sure — but it’s a simple concept. If an operation is idempotent, it can be executed multiple times without changing the result. In general, a good rule of thumb is that you can prevent a whole class of CSRF attacks by only changing things in your DB or on your site by using POST. This means Registration, Logout, Login, and so forth. At the very least, this limits the confused deputy attacks somewhat.

atconway
  • 20,624
  • 30
  • 159
  • 229
-1

One more problem is there. If GET method is used , data is sent in the URL itself . In web server's logs , this data gets saved somewhere in the server along with the request path. Now suppose that if someone has access to/reads those log files , your data (can be user id , passwords , key words , tokens etc. ) gets revealed . This is dangerous and has to be taken care of .

In server's log file, headers and body are not logged but request path is . So , in POST method where data is sent in body, not in request path, your data remains safe .

-2

i think that reading this resource: http://www.servicedesignpatterns.com/WebServiceAPIStyles could be helpful to you to make difference between message API and resource api ?

Milan Svitlica
  • 645
  • 4
  • 9
  • Sorry this link does not at all help answer the very specific question I am asking about using a HTTP GET in scenarios where a HTTP POST should be used. – atconway May 09 '12 at 15:36
  • in your question you provided url which should not be part of REST API and it has typical RPC semnatic where you put method name in url: addTotalAmount – Milan Svitlica May 09 '12 at 15:44
  • It was a pseudocode made up example of an improper REST call to help extract answers to my question. – atconway May 09 '12 at 15:47