On Mon, 2013-07-01 at 13:12 -0500, Endi Sukma Dewata wrote:
On 7/1/2013 11:37 AM, Ade Lee wrote:
I also added a Change Profile State operation: http://pki.fedoraproject.org/wiki/TPS_REST_Interface#Change_Profile_State
The way this is written, it looks like you are just doing a POST to the /tps/rest/profiles/<ProfileID> and passing in "action" as a parameter. Thats not very RESTful at all.
I think we want: /tps/rest/profiles/{id}/{action}
where {action} is approve etc. This is also consistent with how we have done this for cert-requests etc. as well.
This is where I'd like to see the current API changed. These actions (e.g. approve, enable) are not resources or collections. None of the other operations (GET, PUT, DELETE) make sense on actions.
On the other hand, using POST to process data is a valid & RESTful operation. POST request should be sent to a resource, and the resource that we want to handle these actions is the target of the action (i.e. profile).
According to POST definition: * The actual function performed by the POST method is determined by the server and is usually dependent on the Request-URI. * The action performed by the POST method might not result in a resource that can be identified by a URI. * Example: - Providing a block of data, such as the result of submitting a form, to a data-handling process;
According to http://www.ietf.org/rfc/rfc2616.txt (9.6 PUT):
The URI in a POST request identifies the resource that will handle the enclosed entity. That resource might be a data-accepting process, a gateway to some other protocol, or a separate entity that accepts annotations.
Endi, the above definition is what has been referred to as overloaded-POST. Basically, its the way the whole RPC world uses the web. It would be entirely RESTful to create an interface using only POST - but wouldn't exactly be a Restful Oriented Architecture (ROA). Similarly one could create an entire interface using just GET and POST, entirely RESTful but not ROA. I looked back into my REST resources - in particular, Restful Web Services by Leonard Richardson and Sam Ruby, to find some standard practices/ advice to counter this approach. What I found was in fact the opposite. Let me quote Richardson: URIs are supposed to designate resources, not operations on the resources. This means it’s almost never appropriate to put the names of operations in your URIs. If you have a URI that looks like /object/do-operation, you’re in danger of slipping into the RPC style. Nobody wants to link to do-operation: they want to link to the object. Expose the operation through the uniform interface, or use overloaded POST if you have to, but make your URIs designate objects, not operations on the objects. So according to Richardson at least, its more RESTful to use overloaded POST and a query variable then to do what we have been doing.
Also, POST-ing to /tps/rest/profiles/{id} will be more future-proof in case we add/remove actions later.
Yes, this is a good point, although I can't shake the feeling that this makes the interface less intuitive and less discoverable. The actions we have exposed as for example, POST /certrequest/{id}/approve are basic operations that we currently expose and will want to expose in the future. POST /certrequest/{id} with action=approve seems more RPC-like in some way. Maybe its because the above mechanism really is RPC-like (because it uses overloaded POST) and using the action variable just makes that more apparent. Or maybe I need to shake the habit of creating URLs. If we decide to do this, we should consider changing the existing interfaces to follow this practice, before too many clients are written. Incidentally, there is a case where POST /foo/operation is acceptable and that is where you are in fact providing a processor to do an operation and are not generating resources. An example of this is in the TKS, where we request generation of a session key to communicate with a token.