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.