Rather than mentally mapping REST verbs onto traditional CRUD verbs, I recall a quote from TBL to the effect of "Uniform Resource Locator is the term you get when you squeeze 'remote object reference' through a standards process". I think of PUT as being like Python's __init__ method, constructing a new instance with the given details; DELETE is like Python's __del__ method, cleaning up references and removing it; GET is like Python's __str__ method, returning a readable representation of the object's state, and POST is like Python's __call__, invoking the object as a function with some given arguments and who-knows-what side-effects.
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.
I am not sure about "Update = POST if you are requesting the server to update one or more subordinates of the specified resource" - seems to me that if the subordinate updates are idempotent - then this can be PUT, why not. But going a bit further - of all the server side algorithms used for Create calls the most used one is computing the primary keys for auto increment columns. So if you are not using some special database functions - a Create needs to be POST if the primary key is auto-increment and can be PUT otherwise.
In regards to the Update PUT vs Update POST, with the PUT you can only address a single resource. So while the Update POST maybe idempotent, to accomplish the same thing with a PUT, you would have to issue multiple PUTs to address all of the resources that were updated in the POST.
Comments
Rather than mentally mapping REST verbs onto traditional CRUD verbs, I recall a quote from TBL to the effect of "Uniform Resource Locator is the term you get when you squeeze 'remote object reference' through a standards process". I think of PUT as being like Python's __init__ method, constructing a new instance with the given details; DELETE is like Python's __del__ method, cleaning up references and removing it; GET is like Python's __str__ method, returning a readable representation of the object's state, and POST is like Python's __call__, invoking the object as a function with some given arguments and who-knows-what side-effects.
His key point:
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.
I am not sure about "Update = POST if you are requesting the server to update one or more subordinates of the specified resource" - seems to me that if the subordinate updates are idempotent - then this can be PUT, why not. But going a bit further - of all the server side algorithms used for Create calls the most used one is computing the primary keys for auto increment columns. So if you are not using some special database functions - a Create needs to be POST if the primary key is auto-increment and can be PUT otherwise.
In regards to the Update PUT vs Update POST, with the PUT you can only address a single resource. So while the Update POST maybe idempotent, to accomplish the same thing with a PUT, you would have to issue multiple PUTs to address all of the resources that were updated in the POST.
I think of PUT as PUT == (over)write.
The effect of a POST then comes down to the definition of that "custom" processing. This is outside the scope of HTTP; don't conflate the two.