WhiteHouse / api-standards

3.08k stars 901 forks source link

POST is not always "create" and PUT is not always "update". #13

Open inadarei opened 11 years ago

inadarei commented 11 years ago

This is somewhat minor, but the document says that HTTP POST is a "Create". That is not correct. There is no one-to-one mapping between CRUD and HTTP verbs. It boils down to whether the operation is idempotent or not.

HTTP POST is non-idempotent, HTTP PUT is idempotent.

As for CRUD: Create can be both idempotent (if you provide ID of the record that ought to be created, e.g. you are creating a user with specific user_id) or non-idempotent (if you provide data but not the ID). So there're many cases where PUT is absolutely fine for a Create operation.

Furthermore, many services do not support anything but GETor POST. This is because browsers do not support any other verb so lots of proxies and most CDNs also only implement GET and POST with zero support for anything else. We have had some conversations with major CDN providers to address this very issue and I know some of them are actively working on it. Point is: a lot of pragmatic APIs implement POST for "delete" and "update" with so-called Method Override.

Speaking of which, this document could probably use a word or two about method overrides.

benbunk commented 11 years ago

I'm not entirely sure, but it seems that the HTTP Verbs chart https://github.com/WhiteHouse/api-standards#http-verbs is trying to avoid the sort of ambiguity that the HTTP protocol introduces (http://tools.ietf.org/html/rfc2616#page-51) in regard to POST, PUT, and method overrides.

For instance the chart says the the PUT method should only update and if the entity doesn't exist it should return an error. In the HTTP spec it is entirely valid for an origin server to only update entities when the PUT method is used as long as the server returns the correct status code

"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."

(http://tools.ietf.org/html/rfc2616#section-9.6) The operative word is "can" essentially allowing the server to choose if it wants to implement the create operation or not. While in general it is perfectly acceptable to create an entity with PUT I believe the spirit of this document is to avoid such ambiguity. The same goes for POST and method overrides.

However, there is some ambiguity that isn't clarified here in regards to the responses from the PUT and POST methods. For instance with POST if server creates an entity that results in a new URI then,

If a resource has been created on the origin server, the response SHOULD be 201 (Created) and contain an entity which describes the status of the request and refers to the new resource, and a Location header (see section 14.30).

(http://tools.ietf.org/html/rfc2616#section-9.5) The operative word being "should" which is even written in all caps to draw attention to itself in the document. Meaning that it doesn't really need to behave this way. So clarification would be appreciated.

Further if the action doesn't result in an entity with a URI we know it's appropriate but not required to return a 200 or 201 response.

"The action performed by the POST method might not result in a resource that can be identified by a URI. In this case, either 200 (OK) or 204 (No Content) is the appropriate response status, depending on whether or not the response includes an entity that describes the result."

(http://tools.ietf.org/html/rfc2616#section-9.5) Again, clarification here would be good. It would seem this type of behavoir is really geared more towards the method overloading aspect of the POST method and may not need clarification if there won't be any generic actions being created with the POST method.