Why use HTTP PUT and DELETE methods instead of POS

2019-01-07 13:35发布

new_story GET     /story/new(.:format)  {:action=>"new", :controller=>"stories"}
edit_story GET     /story/edit(.:format) {:action=>"edit", :controller=>"stories"}
     story GET     /story(.:format)      {:action=>"show", :controller=>"stories"}
           PUT     /story(.:format)      {:action=>"update", :controller=>"stories"}
           DELETE  /story(.:format)      {:action=>"destroy", :controller=>"stories"}
           POST    /story(.:format)      {:action=>"create", :controller=>"stories"}

In web work I have done with other technologies I only ever used GET and POST methods. But with RESTful routes in Rails, by default the PUT and DELETE methods are used for the update and destroy actions. What's the advantage or need for using PUT and DELETE? I assume these methods are just another way of doing POST - but why not just stick with POST?

4条回答
来,给爷笑一个
2楼-- · 2019-01-07 14:05

That'd be kind of like asking why "delete" a file when you could just set its contents to zero bytes and the file system would just treat that as a delete. HTTP has supported verbs other than GET/POST forever but the way SOAP evolved kinda twisted the original meaning of those verbs. REST is a simpler, back to basics approach that uses the verbs as they were intended instead of inventing some new verb concept inside of the payload.

查看更多
我命由我不由天
3楼-- · 2019-01-07 14:08

Here's the "methods" section of the HTTP 1.1 spec; it defines lots of methods, and they all have different benefits and tradeoffs. POST is the most flexible, but the tradeoffs are numerous: it's not cacheable (so the rest of the internet can't help you scale), it isn't safe or idempotent so the client can't just resend it gets an error, and it is no longer clear exactly what you're trying to accomplish (because it's so flexible). I'm sure there are others but that ought to be sufficient. Given all that, if the HTTP spec defines a method that does exactly what you want your request to do, there's no reason to send a POST instead.

The reason POST is so common is that, historically at least, web browsers only supported GET and POST. Since GET is defined to be safe and idempotent (even though many applications don't adhere to that), the only safe way to modify data was to send a POST. With the rise of AJAX and non-browser clients, that is no longer true.

BTW, the mapping @mipadi gave is the standard mapping, but it isn't the only valid one. Amazon S3, for instance, uses PUT to create resources. The only reason to use POST is if the client doesn't have sufficient knowledge to create the resource, e.g., you back your resources with a relational database and use artificial surrogate keys.

查看更多
混吃等死
4楼-- · 2019-01-07 14:13

The advantage is mostly semantic, and can also simplify URLs to an extent. The different HTTP methods map to different actions:

POST   => create a new object
DELETE => delete an object
PUT    => modify an object
GET    => view an object

Then, in theory, you can use the same URL, but interact with it using different methods; the method used to access the resource defines the actual type of operation.

In practice, though, most browsers only support HTTP GET and POST. Rails uses some "trickery" in HTML forms to act as though a PUT or DELETE request was sent, even though Rails is still using GET or POST for these methods. (This explains why you might not have used DELETE or PUT on other platforms.)

查看更多
看我几分像从前
5楼-- · 2019-01-07 14:24

I just wanted to add something to the accepted answer because his definition of the http verbs are incorrect. They all have a spec which "should" be followed and you can create/update/delete with multiple http verbs based on the specs.

I am going to highlight some of the important bits in the RFC 2616 by W3

I'm going to start with PUT because in my opinion it has the most confusion surrounding it.

  • PUT is used for both create/update PUT updates by completely replacing the resource on the server with the resource sent in the request

For example

You make this call to my api

PUT        /api/person
{
     Name: John,
     email: jdoe@hra.com
}

my Server has this resource living on the server

{
     Name: Jane,
     email: jdoe@hra.com
}

Now my existing resource is completely replaced by what you sent over and this is what I have on my server.

{
     Name: John,
     email: jdoe@hra.com
}

So if you PUT and only send an email in the body

PUT        /api/person
{
     email: jdoe@hra.com
}

My Server will completely replace the entity

{
     Name: Jane,
     email: jdoe@hra.com
}

With

{
     email: jdoe@hra.com
}

And Name will be gone. Partial updates are for PATCH but I use POST for that anyway.

  • One of the main reasons why we create/update with put is because it is idempotent.

It's just a fancy term and the basic definition of it is multiple identical requests are the same for a single request.

Example

Suppose I PUT a file to api/file if the origin server does not find that file it will create one. If it does find a file it will completely replace the old file with the one I sent over. This ensures that one file is ever created and updated. If no file exists and you call PUT 5 times, the first time it creates a file then the other 4 times it replaces the file with what you send over. If you call a POST 5 times to create it will create 5 files.

  • You PUT to that exact URI. If you don't you have to send a 301 (Moved Permanently) to the user and allow then make a choice whether or not to redirect the request. Most times the server you PUT to usually hosts the resource and takes care of updating it

Those are the major points in when to use PUT

As far as POST is concerned

  • You can also create/update and then some...

As I mentioned above there are a few key differences.

  • Post is more General. In what ways? some other examples include a gateway to other protocols, it could take the response and send it to some data handler out in the middle of yonder, or it can extend some sort of functionality.
  • Post doesn't have the restriction of "To the exact URI or notifiy" for examplePOST can append a resource to an existing collection and decide where it's stored.

Now what about Delete Why don't I just POST?

When you DELETE, the server SHOULD NOT respond with success unless you delete the resource or move it to an inaccessible location at the time the response is sent.

Why is that important? What if you call DELETE but the resource has to go through "APPROVAL" before being deleted? If the delete can be rejected you can't send a successful error code and if you do follow the basic specs on this it's confusing to the caller. Just an example I'm sure you can think of many others.

I just highlighted some of the major points on when to use the common Http verbs

查看更多
登录 后发表回答