outmoded / postmile

Collaborative list making tool written in Node.js
Other
404 stars 53 forks source link

PUT verb being used in a non-idempotent way #38

Open fernandoacorreia opened 13 years ago

fernandoacorreia commented 13 years ago

As stated in the HTTP 1.1 specification:

"Methods can also have the property of "idempotence" in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request. The methods GET, HEAD, PUT and DELETE share this property. "

(http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html)

As implemented, repeated PUT request to e.g. "/project/{projectId}/task" will not be idempotent; each request to the same URL will create a new task.

That would be the semantics expected of POST, not of PUT. In short, PUT replaces the content of a URL, POST adds content subordinate to a URL.

"The PUT method requests that the enclosed entity be stored under the supplied Request-URI. If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server. If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI. If a new resource is created, the origin server MUST inform the user agent via the 201 (Created) response. If an existing resource is modified, either the 200 (OK) or 204 (No Content) response codes SHOULD be sent to indicate successful completion of the request."

and

"The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line."

This semantic inconsistency would be more obvious if the URL emphasized that the resources are COLLECTIONS, not individual objects. For instance:

""/projects/{projectId}/tasks"

is a list of tasks, not a single task, and "/projects" is a list of projects, not a single project.

The suggested resolution is to replace PUT with POST when the expected action is to create a new resource subordinate to a URL and, optionally, pluralize the resource names to make that clearer.

See also:

http://stackoverflow.com/questions/630453/put-vs-post-in-rest

http://jcalcote.wordpress.com/2008/10/16/put-or-post-the-rest-of-the-story/

http://vincenthomedev.wordpress.com/2008/12/18/put-vs-post-in-restful-web-service/

http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Idempotent_methods_and_web_applications