tags:

views:

1161

answers:

14

What is the practical benefit of using HTTP GET, PUT, DELETE, POST, HEAD? Why not focus on their behavioral benefits (safety and idempotency), forgetting their names, and use GET, PUT or POST depending on which behavior we want?

Why shouldn't we only use GET, PUT and POST (and drop HEAD, DELETE)?

+20  A: 

The [REST][1] approach uses POST, GET, PUT and DELETE to implement the CRUD rules for a web resource. It's a simple and tidy way to expose objects to requests on the web. It's web services without the overheads.

Just to clarify the semantic differences. Each operation is rather different. The point is to have nice HTTP methods that have clear, distinct meanings.

POST creates new objects. The URI has no key; it accepts a message body that defines the object. SQL Insert. [Edit While there's no technical reason for POST to have no key, the REST folks suggest strongly that for POST to have distinct meaning as CREATE, it should not have a key.]

GET retrieves existing objects. The URI may have a key, depends on whether you are doing singleton GET or list GET. SQL Select

PUT updates an existing object. The URI has a key; It accepts a message body that updates an object. SQL Update.

DELETE deletes an existing object. The URI has a key. SQL Delete.

Can you update a record with POST instead of PUT? Not without introducing some ambiguity. Verbs should have unambiguous effects. Further, POST URI's have no key, where PUT must have a key.

When I POST, I expect a 201 CREATED. If I don't get that, something's wrong. Similarly, when I PUT, I expect a 200 OK. If I don't get that, something's wrong.

I suppose you could insist on some ambiguity where POST does either POST or PUT. The URI has to be different; also the associated message could be different. Generally, the REST folks take their cue from SQL where INSERT and UPDATE are different verbs.

You could make the case that UPDATE should insert if the record doesn't exist or update if the record does exist. However, it's simpler if UPDATE means UPDATE and failure to update means something's wrong. A secret fall-back to INSERT makes the operation ambiguous.

If you're not building a RESTful interface, then it's typical to only use GET and POST for retrieve and create/update. It's common to have URI differences or message content differences to distinguish between POST and PUT when a person is clicking submit on a form. It, however, isn't very clean because your code has to determine if you're in the POST=create case or POST=update case.

S.Lott
Yes, but that doesn't answer my question.I was asking why you would even bother using PUT, DELETE when GET, POST will do the job just fine? Who cares what their names are if the behavior is the same?
Gili
The behavior isn't the same. PUT is not the same as POST. PUT corresponds to update, POST corresponds to create. The semantics are entirely different.
S.Lott
I see no technical reason why you couldn't update a record using POST. There might be a convention that says you should use one or the other, but on a technical level I don't think it makes a difference.
Gili
Verbs should have unambiguous meanings.
S.Lott
We should probably remember that the original question didnn't mention REST. I you are designing a rest system then yes, you would want to use those verbs. If you are designing a web application and not worried about REST then you would probably only use POST or GET.
Dr8k
The comparison to INSERT and UPDATE is not valid. PUT will create a resource if it does not already exist. To create an entity with POST you don't POST to the same place as you PUT, There are a enough differences that is disingenuous to try and consider them equivalent.
Darrel Miller
PUT is to create a resource when the URL is known
davetron5000
@S.Lott Can I humbly suggest that you do some more reading on REST? If you posted that explanation on the REST-discuss Yahoo group you would get torn apart.POST by its very definition in RFC2616 is ambiguous. It does not have to create a resource.
Darrel Miller
@Darrel Miller: True, POST is ambiguously defined. It's often used to create things, in spite of the ambiguity. The question was on why have all those methods -- not are the methods ambiguous.
S.Lott
"Further, POST URI's have no key, where PUT must have a key."Nothing prevents you from using keys in all your POST URIs. Does it?
Gili
@Gili: While there's no *technical* reason, it would create ambiguity. It's nice to have a lot of precise verbs -- we don't communicate among people using only the verbs "BE" and "DO". I think that same thing should be true of REST.
S.Lott
Actually, REST has nothing to do with CRUD.
Wahnfrieden
@Wahnfrieden: While true (REST != CRUD) there are obvious parallels we can exploit.
S.Lott
+4  A: 

Why do we need more than POST? It allows data to flow both ways, so why would GET be needed? The answer is basically the same as for your question. By standardizing the basic expectations of the various methods other processes can better know what to do.

For example, intervening caching proxies can have a better chance of doing the correct thing.

Think about HEAD for instance. If the proxy server knows what HEAD means then it can process the result from a previous GET request to provide the proper answer to a HEAD request. And it can know that POST, PUT and DELETE should not be cached.

Darron
I suspect that HTTP POST causes proxy servers to dump any cached entries associated with that URL (but I can't find this discussed either way in the HTTP specification). If this is true, doesn't POST replace PUT and DELETE?
Gili
According to the specification, as I remember it:GET -- fetch data.PUT -- send data, that should be fetchable in the future.POST -- send data to a "program" and fetch a response.A cache will probably be designed to match these definitions.
Darron
+1  A: 

Not all hosters don't support PUT, DELETE.

I asked this question, in an ideal world we'd have all the verbs but....:

http://stackoverflow.com/questions/23963/restful-web-services-and-http-verbs

Kev
A: 

To limit ambiguity which will allow for better/easier reuse of our simple REST apis.

Justin Bozonier
A: 

You could use only GET and POST but then you are losing out on some of the precision and clarity that PUT and DELETE bring. POST is a wildcard operation that could mean anything. PUT and DELETE's behaviour is very well defined. If you think of a resource management API then GET, PUT and DELETE probably cover 80%-90% of the required functionality. If you limit yourself to GET and POST then 40%-60% of your api is accessed using the poorly specified POST.

Darrel Miller
A: 

The web server war from the earlier days probably caused it.

In HTTP 1.0 written in 1996, there were only GET, HEAD, and POST. But as you can see in Appendix D, vendors started to add their own things. So, to keep HTTP compatible, they were forced to make HTTP 1.1 in 1999.

However, HTTP/1.0 does not sufficiently take into consideration the effects of hierarchical proxies, caching, the need for persistent connections, or virtual hosts. In addition, the proliferation of incompletely-implemented applications calling themselves "HTTP/1.0" has necessitated a protocol version change in order for two communicating applications to determine each other's true capabilities.

This specification defines the protocol referred to as "HTTP/1.1". This protocol includes more stringent requirements than HTTP/1.0 in order to ensure reliable implementation of its features.

eed3si9n
A: 

Web applications using GET and POST allow users to create, view, modify and delete their data, but do so at a layer above the HTTP commands originally created for these purposes. One of the ideas behind REST is a return to the original intent of the design of the Web, whereby there are specific HTTP operations for each CRUD verb.

Also, the HEAD command can be used to improve the user experience for (potentially large) file downloads. You call HEAD to find out how large the response is going to be and then call GET to actually retrieve the content.

John Topley
A: 

See the following link for an illustrative example. It also suggests one way to use the OPTIONS http method, which hasn't yet been discussed here.

johnstok
A: 

GET, PUT, DELETE and POST are holdovers from an era when sophomores thought that a web page could be reduced to a few hoighty-toity principles.

Nowadays, most web pages are composite entities, which contain some or all of these primitive operations. For instance, a page could have forms for viewing or updating customer information, which perhaps spans a number of tables.

I usually use $_REQUEST[] in php, not really caring how the information arrived. I would choose to use GET or PUT methods based on efficiency, not the underlying (multiple) paradigms.

dar7yl
someone want to explain self? I'm curious.
dar7yl
are you asking about the down-vote?
Mark Cidade
Yes, (you could have replied w/o this handshaking)My point is that most web pages don't conform to the paradigm ideal, and GET and PUT differences cannot even be enforced, so the underlying concept is flawed.
dar7yl
+11  A: 

POST has no guarantees of safety or idempotency. That's one reason for PUT and DELETE—both PUT and DELETE are idempotent (i.e., 1+N identical requests have the same end result as just 1 request).

PUT is used for setting the state of a resource at a given URI. When you send a POST request to a resource at a particular URI, that resource should not be replaced by the content. At most, it should be appended to. This is why POST isn't idempotent—in the case of appending POSTS, every request will add to the resource (e.g., post a new message to a discussion forum each time).

DELETE is used for making sure that a resource at a given URI is removed from the server. POST shouldn't normally be used for deleting except for the case of submitting a request to delete. Again, the URI of the resource you would POST to in that case shouldn't be the URI for the resource you want to delete. Any resource for which you POST to is a resource that accepts the POSTed data to append to itself, add to a collection, or to process in some other way.

HEAD is used if all you care about is the headers of a GET request and you don't want to waste bandwidth on the actual content. This is nice to have.

Mark Cidade
+2  A: 

No one posted the kind of answer I was looking for so I will try to summarize the points myself.

"RESTful Web Services" chapter 8 section "Overloading POST" reads: "If you want to do without PUT and DELETE altogether, it’s entirely RESTful to expose safe operations on resources through GET, and all other operations through overloaded POST. Doing this violates my Resource-Oriented Architecture, but it conforms to the less restrictive rules of REST."

In short, replacing PUT/DELETE in favor of POST makes the API harder to read and PUT/DELETE calls are no longer idempotent.

Gili
A: 

There are http extensions like WebDAV that require additional functionally.

http://en.wikipedia.org/wiki/WebDAV

JaredCacurak
+1  A: 

In a word:

idempotency

In a few more words:

GET = safe + idempotent

PUT = idempotent

DELETE = idempotent

POST = neither safe or idempotent

'Idempotent' just means you can do it over and over again and it will always do exactly the same thing.

You can reissue a PUT (update) or DELETE request as many times as you want and it will have the same effect every time, however the desired effect will modify a resource so it is not considered 'safe'.

A POST request should create a new resource with every request, meaning the effect will be different every time. Therefore POST is not considered safe or idempotent.

Methods like GET and HEAD are just read operations and are therefore considered 'safe' aswell as idempotent.

This is actually a pretty important concept because it provides a standard/consistent way to interpret HTTP transactions; this is particularly useful in a security context.

Mike K
So my point then becomes, why not focus on the various categories instead of the method name?1) When you want safe + idempotent only use GET, eliminating HEAD.2) When you want idempotent only use PUT, eliminating DELETE.3) When you want neither only use POST.
Gili
+1  A: 

HEAD is really useful for determining what a given server's clock is set to (accurate to within the 1 second or the network round-trip time, whichever is greater). It's also great for getting Futurama quotes from Slashdot:

~$ curl -I slashdot.org
HTTP/1.1 200 OK
Date: Wed, 29 Oct 2008 05:35:13 GMT
Server: Apache/1.3.41 (Unix) mod_perl/1.31-rc4
SLASH_LOG_DATA: shtml
X-Powered-By: Slash 2.005001227
X-Fry: That's a chick show. I prefer programs of the genre: World's Blankiest Blank.
Cache-Control: private
Pragma: private
Connection: close
Content-Type: text/html; charset=iso-8859-1

For cURL, -I is the option for performing a HEAD request. To get the current date and time of a given server, just do

curl -I $server | grep ^Date

Adam Rosenfield