The crux of the issue comes down to a concept known as idempotency. An operation is idempotent if a sequence of two or more of the same operation results in the same resource state as would a single instance of that operation. According to the HTTP 1.1 specification, GET, HEAD, PUT and DELETE are idempotent, while POST is not. That is, a sequence of multiple attempts to PUT data to a URL will result in the same resource state as a single attempt to PUT data to that URL, but the same cannot be said of a POST request. This is why a browser always pops up a warning dialog when you back up over a POSTed form. “Are you sure you want to purchase that item again!?” (Would that the warning was always this clear!)
After that discussion, a more realistic mapping would seem to be:
- Create = PUT iff you are sending the full content of the specified resource (URL).
- Create = POST if you are sending a command to the server to create a subordinate of the specified resource, using some server-side algorithm.
- Retrieve = GET.
- Update = PUT iff you are updating the full content of the specified resource.
- Update = POST if you are requesting the server to update one or more subordinates of the specified resource.
- Delete = DELETE.
NOTE: “iff” means “if and only if”.
Create can be implemented using an HTTP PUT, if (and only if) the payload of the request contains the full content of the exactly specified URL. For instance, assume a client issues the following Create OR Update request:
HTTP/1.1 PUT /GrafPak/Pictures/1000.jpg ... <full content of 1000.jpg ... >
This command is idempotent because sending the same command once or five times in a row will have exactly the same effect; namely that the payload of the request will end up becoming the full content of the resource specified by the URL, “/GrafPak/Pictures/1000.jpg”.
On the other hand, the following request is NOT idempotent because the results of sending it either once or several times are different:
HTTP/1.1 POST /GrafPak/Pictures ... <?xml version="1.0" encoding="UTF-8"?> <GrafPak operation="add" type="jpeg"> <[CDATA[ <full content of some picture ... > ]]> </GrafPak>
Specifically, sending this command twice will result in two “new” pictures being added to the Pictures container on the server. According to the HTTP 1.1 specification, the server’s response should be something like “201 Created” with Location headers for each response containing the resource (URL) references to the newly created resources–something like “/GrafPak/Pictures/1001.jpg” and “/GrafPak/Pictures/1002.jpg”.
The value of the Location response header allows the client application to directly address these new picture objects on the server in subsequent operations. In fact, the client application could even use PUT to directly update these new pictures in an idempotent fashion.
What it comes down to is that PUT must create or update a specified resource by sending the full content of that same resource. POST operations, on the other hand, tell a web service exactly how to modify the contents of a resource that may be considered a container of other resources. POST operations may or may not result in additional directly accessible resources.
An Awesome video about Rest api, which talks about idempotent from 21minute