What are the advantages of using the right HTTP methods?

Asked

Viewed 4,219 times

70

I have seen many people defending the use of HTTP methods correctly, that is, respecting the semantics of the methods defined in the specification when making a request. GET should only be used to recover data, and never for actions that cause side effects. Methods PUT and DELETE often should be used in place of the POST.

But it’s an obvious fact that very few people on the web do this, in practice GET and POST are used almost exclusively for various reasons which are not.

I would like to know the advantages of correct use, and the disadvantages of what is done in practice, beyond the dogma of "right" and "wrong" and the semantic question.

  • 3

    I will vote to close because the question only allows empty answers :P

  • 9

    Close is with POST or DELETE?

  • 3

    The correct semantics should allow to be CLOSE :)

  • Related: http://stackoverflow.com/questions/12142652/what-is-the-usefulness-of-put-and-delete-http-request-methods

  • @Victor So the correct one to close would be PUT, right? I doubt this site will do that (I tried to test it now, but I couldn’t figure it out). And what’s the problem with not doing it? Deep down, that’s my question.

  • I’m trying to come up with an answer to your question, but the more I research, the more confused I get. A half hour ago I advocated the use of DELETE, PUT and other recently added methods such as PATCH and Webdav. However, the more I research on this, the more I become convinced that these methods seem to be superfluous and that at bottom it is nothing more than semantic preciousness without much practical meaning.

  • 2

    @Victor Yeah, I think something similar, but I hope someone will convince me otherwise :)

  • I think the question will only do the opposite :) I would also like to see good reasons for current use, but...

  • @Qmechanic73 This link there is POST vs GET only, that’s the easy part. What the bfavaretto is asking for is about PUT/DELETE vs POST.

  • 8

    I found this reply from @Bruno very interesting: http://answall.com/a/16930/14262

  • Question of the hour :)

Show 6 more comments

1 answer

83


Let’s start by looking at our approaches to doing a CRUD on a server and forging some Urls to analyze. The first approach (let’s call it To) is to use the appropriate HTTP verbs:

GET http://www.example.com/somepath/resource.txt
PUT http://www.example.com/somepath/resource.txt
DELETE http://www.example.com/somepath/resource.txt
PATCH http://www.example.com/somepath/resource.txt

The second approach (B) is to use only GET and POST and place verbs in Urls:

GET http://www.example.com/somepath/resource.txt
POST http://www.example.com/somepath/resource.txt/put
POST http://www.example.com/somepath/resource.txt/delete
POST http://www.example.com/somepath/resource.txt/patch

The third approach (C) is to use only GET and POST and set form fields in the POST:

GET http://www.example.com/somepath/resource.txt

POST http://www.example.com/somepath/resource.txt
action=put&content=...

POST http://www.example.com/somepath/resource.txt
action=delete

POST http://www.example.com/somepath/resource.txt
action=patch&data=...

Now, let’s look at the advantages of the To on approaches B and C:

Advantage 1: All actions have the same URL and therefore they all clearly refer to actions on the same resource. If you have uploaded a feature with PUT, you are expected to get the same feature when using GET, change it with PATCH and destroy it with DELETE.

Advantage 2: PUT, DELETE and PATCH are idempotent, but POST is not. POST requests are not cached and generally cannot be repeated, unlike with PUT, DELETE and PATCH. But in the case where the POST represents a disguised PUT, DELETE or PATCH, they should be cacheable and repeatable, but the browser or some other agent will not know this, because the semantics are within the application and not in the protocol.

Advantage 3: The PUT, DELETE and PATCH methods are simpler pure than when encapsulated in disguised Posts. With PUT, for example, your request will contain as body only the resource you want to use to perform the upload and nothing else. If you use the POST instead, you will have to manage with multiple form fields and maybe with special rules for the enctype="multipart/form-data".

Advantage 4: The HTTP verb used makes it clear which action is being performed on the resource and therefore the expected behavior is well defined. If we are limited to GET and POST only, the URL will have to be changed (approach B) or you will be required to define custom form fields (approach C). The ideal is that the Urls were preserved and no custom field was needed.

Advantage 5: The processing of POST is not so well defined from the point of view of HTTP, as its semantics depends entirely on the application, unlike what happens with PUT, DELETE and PATCH. In HTTP, POST denotes only sending data to the server, but says nothing about how this data will be processed.

However the advantages of the To end there. Now that I have listed them, I will present the disadvantages and also deconstruct the advantages presented:


Disadvantage 6: Browsers only support forms with POST and GET actions. This is usually sufficient reason to force developers to abandon PUT and DELETE, since browsers will not be able to use them effectively and simply.

You can use the other methods via AJAX. But in forms you cannot because as explained by Ian Hickson PUT wouldn’t make sense because it doesn’t make sense to upload the content of a form, but just upload resources, which is not a form. DELETE makes no sense in forms because the DELETE method has no body and the form represents the body of the request. (link I used to find this information).

As a result, in the HTML5 specification only POST and GET are accepted as form submission methods:

The method and formmethod content Attributes are enumerated Attributes with the following Keywords and States:

  • The keyword get, Mapping to the state GET, indicating the HTTP GET method.

  • The keyword post, Mapping to the state POST, indicating the HTTP POST method.

The invalid value default for These Attributes is the GET state. The Missing value default for the method attribute is also the GET state. (There is no Missing value default for the formmethod attribute.)

Translating this into English:

The content of attributes method and formmethod sane listed attributes with the following keywords and states:

  • The keyword get, mapping to the state GET, indicating the HTTP GET method.

  • The keyword post, mapping to the state POST, indicating the HTTP POST method.

The assumed value when invalid for these attributes is the state GET. The assumed value when omitted for the attribute method is also the state GET. (There is no assumed value when omitted for the attribute formmethod.)

Thus, browsers only accept POST and GET in forms.

On the other hand, it is true that maybe this will change in the future, but for now it is so (link I used to find this information).

When/if browsers allow the use of PUT and DELETE in forms, the use of the back button of browsers can avail of the idempotency or cacheability of these methods and show more user-friendly messages than those that occur when trying toif you return to a page that is the result of a POST. This is a small possible future semantic advantage of the approach To, but it really is something perfectly dispensable in practice and although it can solve the problem of disadvantage 6 after the old browsers that do not implement it fall into disuse, it does not solve the problem of disadvantage 7 (see below) and does not give any other significant advantage to the To. When/if this is implemented, we may use PUT and DELETE in Apis, but what we are actually gaining in practice with this?

Note: Thank you to Marcelo Bonifazio for commenting that allowed me to find the reply from Bruno Augusto.

Deconstructing the Advantage 1:

Advantage 1 does not apply only to the To, but also for the approach C, since the URL does not change since the form parameters are not part of the URL.

Moreover, in practice this advantage is not significant over the approach B. So in this case the URL is not identical? What is the problem with this in practice? What happens is that in practice the difference of the Urls does not represent any kind of disadvantage.

Deconstructing the Advantage 2:

So what if the POST isn’t identical? If you have control of the server program and the client program you can implement any cache or repeat mechanism you want. If your client program is the web browser, then it could not cache or repeat the request anyway, because due to disadvantage 6 above, it can not use PUT, DELETE or PATCH by any means other than AJAX, and AJAX requests are neither cacheable nor repeatable (nor should they be).

Therefore, if you are using the browser, the idempotency of these methods means nothing. If on the other hand your client program is customized, then you can decide to cachear or repeat requests as you wish, even if it is a POST (just do it intelligently, caching only what you know is cacheable and just repeating what you know is repeatable). Or, your custom client program can completely ignore the questions of cache and request repetition since this will rarely meet any practical and real need in the case of PUT, DELETE or PATCH.

Deconstructing the advantage 3:

So what if the use of PUT, DELETE or PATCH disguised as POST is a little more complex than them pure? This extra complexity in practice is negligible and is a problem solved and overcome, and it is nothing that a little code on the server does not solve. Often such code is even implemented within frameworks, as with Ruby-on-Rails.

Drawback 7:

In the approach B We are required to modify the URL to specify which action is desired. Again, as explained when I deconstructed advantage 1, this is not usually a real problem in practice. For the approach C, the need to add form parameters also does not usually consist of real disadvantage.

However, in the To the action is specified in the HTTP method. And besides GET, we have PUT, DELETE and recently PATCH and only. We can use the Webdav to get some more methods (such as COPY, MOVE, LOCK and PROPFIND, among others), but we are limited to a predefined set of HTTP verbs, otherwise we are forced to use POST... Or is it not?

Imagine that according to the approach C We have Urls with POST like this:

POST http://www.example.com/somepath/resource.txt
action=banana

POST http://www.example.com/somepath/resource.txt
action=crazy

POST http://www.example.com/somepath/resource.txt
action=lol&type=huebr

POST http://www.example.com/somepath/resource.txt
action=hellokitty

So far so good. If we use the approach B instead, all right too:

POST http://www.example.com/somepath/resource.txt/banana
POST http://www.example.com/somepath/resource.txt/crazy
POST http://www.example.com/somepath/resource.txt/lol&type=huebr
POST http://www.example.com/somepath/resource.txt/hellokitty

Now let’s try to use the approach To in these cases:

BANANA http://www.example.com/somepath/resource.txt
CRAZY http://www.example.com/somepath/resource.txt
LOLHUEBR http://www.example.com/somepath/resource.txt
HELLOKITTY http://www.example.com/somepath/resource.txt

This is fucking ridiculous! OK that inventing custom HTTP methods takes some work and is something very unusual and not recommended to do without having thought about it very well, but it is not impossible (so much so that is what happens in the case of Webdav). This is feasible especially if you have control over both client and server implementation. However, this demonstrates that predefined HTTP verbs PUT, DELETE and PATCH, or even imported from well-known HTTP extensions such as Webdav will only make sense for a significantly small and simple set of actions that you can perform. For the other actions, the behavior and semantics are completely unrelated to the HTTP specification or that of any well-known HTTP extension and are completely on account of the application, and therefore ends up being better, simpler, easier and more practical to stick to the POST in these cases instead of inventing new crazy HTTP methods.

We can still try to save the approach To with something like that:

PUT http://www.example.com/somepath/resource.txt/banana
PUT http://www.example.com/somepath/resource.txt/crazy
PUT http://www.example.com/somepath/resource.txt/lol&type=huebr
PUT http://www.example.com/somepath/resource.txt/hellokitty

Or just that:

PUT http://www.example.com/somepath/resource.txt     (Usa PUT como se fosse BANANA)
PATCH http://www.example.com/somepath/resource.txt   (Usa PATCH como se fosse CRAZY)
COPY http://www.example.com/somepath/resource.txt    (Usa COPY do WebDAV para LOL HUEBR)
MOVE http://www.example.com/somepath/resource.txt    (Usa MOVE do WebDAV para Hello Kitty)

But that does not bring us any benefit, because it ends up throwing out the advantages of the approach To without getting rid of any of the disadvantages. In this bizarre we are only using arbitrary and semantically incorrect methods for stubbornness not to use the POST.

Someone might want to claim that the two forms above are scarecrows that I built from the approach To. Maybe this statement is even correct, but this does not change the fact that in many circumstances the predefined HTTP methods are insufficient and hence the best solution turns out to be to use the good old POST. Also, if the action to be performed is unrelated to what PUT, DELETE, PATCH or any particular HTTP extension (example: Webdav) propose. then I see no other chance to try (unsuccessfully) to save the approach To other than inventing new HTTP methods or forcing the use of existing HTTP methods even if inappropriate.

Deconstructing the advantages 4 and 5:

Due to disadvantage 7, in the approach To, the meaning of the action specified in the verb HTTP only applies to some particular cases, but when we bump into situations where no pre-http verbdefined if it applies, then we will either force the use of a semantically inappropriate HTTP method or we will have to invent new HTTP verbs and in both situations the well-specified semantics goes to the beauty, and it ends up being easier to use the POST (ie, abandon the approach To).

In addition, there is not much advantage in practice to have the action semantics well specified in the HTTP verb, except in the case of GET (and more basic HTTP methods like HEAD, OPTIONS and TRACE), but these are identical in all approaches. What semantics of using PUT and DELETE instead of an equivalent POST brings good and tangible in practice?


Completion: The advantages that the To presents are not significant and useful in practice, but its disadvantages in some cases are worrying and hinder the development of applications. On the other hand the disadvantages of the approaches B and C are of little relevance.

It is true that if you are developing an API that will be used by a custom client program or accessed via AJAX, you can use PUT and DELETE without problems and then avoid the 6 disadvantage of the approach To. However it is also true that you can also use the POST without problems and therefore the approach To will not offer any practical advantage over the approaches B and C.

As a result, I conclude that it’s simpler and easier to stick to the old GET and POST and use any of the approaches B or C. I convinced myself that there is no practical advantage of using PUT, DELETE or PATCH and that they are only a semantic preciousness, in fact these methods are superfluous and they can all be represented by POST.

It is also true that approaches can be combined. Nothing prevents you from having an API where some parties follow the approach To, others follow the approach B and others follow the C, and I can even think of a few reasons to do that (obviously this only applies to methods that are not based on GET). However, this will create an API that will have a Frankenstein style (but this is probably no problem in practice) and the parts of the API that use the approach To do not have many practical technical advantages for doing so, so that this choice will occur by mere whim or preciousness of the developer, or perhaps by some kind of artificial imposition coming from some specification, tool or framework. It is also perfectly possible to provide functionality redundantly, where the same functionality can be available through different approaches (which would be a polymorphic Frankenstein):

PUT http://www.example.com/somepath/resource.txt
POST http://www.example.com/somepath/resource.txt/put

In my personal experience, when I was designing some API through the approach To and bumped into disadvantage 7, even though without realizing it, I end up either using the POST (ie abandoning the approach To pure and creating a Frankenstein) or else I ended up forcing the use of an inappropriate HTTP method, and I believe the same happens with many other developers who try to follow the approach To.

But there’s nothing to save the approach To? Well, if you’re in a scenario where the idempotency of PUT and DELETE (or some other) methods is useful to you, it can make a difference. That is, if you are in a scenario where disadvantage 6 does not apply (especially if/when browsers accept them in forms, or you are using a custom client) and advantage 2 survives deconstruction attempt (that is, cacheability and repeatability exist in practice being well implemented, bringing real benefits to your case and are not or may not or should not be applied selectively to Posts)then you will have a relatively strong positive point in favor of using the PUT and DELETE methods. However in most cases that happen in practice, these situations do not apply or do not make any difference, and I can even visualize cases where the programmer designs the API and forgets that PUT and DELETE are idempotents and ends up using them improperly (and therefore should use POST same).

And now that I’ve finished my answer, let the flamewar debate in the comments. :)

  • 29

    I’ll start with flamewar: that’s not an answer. That’s a course completion article, :)

  • 3

    Really, you should write an article about it :)

  • 3

    Thank you for all the research and comprehensive response! I’ve been thinking too, and in certain services Restful (not all) makes sense the semantically correct use. From everything you said, the cache issue seemed the strongest reason to decide. Sure, you can get around as you mentioned in "deconstructing 2", but to be able to enjoy something ready in this case would be advantageous. I would use if the HTML Forms (and maybe also anchors) allowed you to choose the other methods.

  • @bfavaretto I added a paragraph at the end to show where the A approach can be saved.

  • I would just like to say that in this case there is the specification that recommends @Victor’s A approach... but as we know many are those who like not to follow the specifications claiming advantages. in my opinion a specification exists for some reason. Great response in size and content! when I came to the end I was tired. out of jokes....

  • @chambelix There are cases where the specification is pierced. And in addition, I focused more on the case of the programmer who will invent his REST API using the methods he thinks best. When it is an already defined API, one should usually only obey what it asks for. It seems to me that the main reason that PUT and DELETE exist are semantic issues and idempotency.

  • 3

    @Victor agrees 100% with your comment and I consider that reality often leads us to break the specification... I as a professional do it. However, I must admit that a specification must be respected. I give example: if I develop outside the specification requires me to document everything for future, if follow the specification my documentation does not need to be so exhaustive... this is an example among others.

  • 8

    For some bizarre reason, this reply was not marked as accepted until today. I apologize, error corrected :)

  • It is tiring to read, but very interesting and didactic.

  • Should generate a wiki on the answer.

  • Excuse my ignorance, but what do you mean by cacheability ?

  • @Diegofelipe means something that can be curled. That is, it is a type of information that can be stored in a temporary memory without being searched for in its actual source. For information to be cacheable, it must be information that either never changes or does not generate any problems if it can be seen outdated from time to time. For example, maps of a geographic region are cacheable as they change very slowly and using an outdated version for a few days is not problematic. Already bank transaction data are not cacheable and should always be current.

  • @Victorstafusa thanks for the clarification, nor did I realize that it had to do with cache, therefore the doubt.

  • 1

    simply fantastic the answer and the details, if it is true all this(rsrs), it really does not make sense to use these methods http, because POST may be the best option currently

  • 1

    Congratulations on the answer. We are looking to achieve level 3 of Richardson’s maturity model for our services. And this post, made me question the real need to do this task. Anyway, I’m going to do a little more research to try to form an opinion!

  • 1

    I recommend separating by chapters kkkkkk. Pranks aside, Congratulations for all the research work and for this answer.

Show 11 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.