[Pki-devel] TPS REST interface design

Endi Sukma Dewata edewata at redhat.com
Mon Jul 1 16:51:50 UTC 2013


On 7/1/2013 9:47 AM, Ade Lee wrote:
> The REST guidelines are precisely that - guidelines - and we can choose
> to ignore them at our discretion.   But there are distinct advantages to
> following them.  In particular, when doing so, anyone looking at the API
> knows exactly what is going on.  By using PUT, its clear that the client
> is responsible for providing the resource ID.
>
> REST basically says to use the HTTP spec to determine what operation to
> use.  To see what the REST guideline would be in this case, lets see
> what the HTTP spec says about PUT:
> http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6
>
> 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.

This defines what PUT does, but it doesn't necessarily require us to use 
PUT if we know the resource ID already. The POST is equally valid:

 From http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5:
> 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. POST is designed
> to allow a uniform method to cover the following functions:
>
> - Annotation of existing resources;
> - Posting a message to a bulletin board, newsgroup, mailing list,
>   or similar group of articles;
> - Providing a block of data, such as the result of submitting a
>   form, to a data-handling process;
> - Extending a database through an append operation.
>
> The actual function performed by the POST method is determined by the
> server and is usually dependent on the Request-URI. The posted entity
> is subordinate to that URI in the same way that a file is subordinate
> to a directory containing it, a news article is subordinate to a
> newsgroup to which it is posted, or a record is subordinate to a
> database.

Adding a new user or profile into a collection would be analogous to the 
above examples.

On 7/1/2013 9:47 AM, Ade Lee wrote:
> The point you make about possibly overwriting an existing resource is
> valid -- but the answer there is etags.  And as e will be writing the
> first clients for this, we can safely say that - yes - all clients will
> support etags.

With REST anybody can write their own client or use generic tools to 
access our interface. Of course the client must provide the required 
parameters in all requests, but if we require clients to use what 
supposed to be optional in REST we will reduce the number of clients 
that can use the interface.

REST provides two different -- but valid -- mechanisms: PUT and POST. I 
think there are enough reasons to use separate operations for create and 
update:
* Different behavior: create should fail if entry already exists where 
as update should fail if entry doesn't exist.
* Different security: not all users are allowed to create an entry.
* Server won't need to check if entry already exists.
* If operation fails because entry exists/doesn't exist the client will 
know it.
* Client won't need to determine which URL to use.
* It works without ETag. Client won't need to do an extra GET operation.
* Client can still use ETag if concurrency is a concern.

Here's what Bill Burke said when we discussed about this when we're 
discussing the users interface:

On 5/24/2012 11:33 AM, Bill Burke wrote:
>> 1. Considering all the requirements, should CREATE and UPDATE be
>> handled by a single or separate methods?
>
> Because you only want admins to be able to create a user, and non-admins
> can update users, you should probably use the @Post method to create,
> and not use @Put for creation.
>
> @POST @Path("/users") create();
>
> for
>
> @PUT @Path("/users/{id}") update(); you should throw a 404 if the user
> doesn't exist.

>> Suppose the security requirements are the same for both operations,
>> would you design it differently?
>
> All depends whether or not I wanted to rely on the client to pick the
> URI or not.  I usually use the @POST /users because it gives the server
> a lot of flexibility on what the returned URI (in the Location header)
> looks like.

On 7/1/2013 9:47 AM, Ade Lee wrote:
> Just because we may not implement etags in the first iteration does not
> mean that we should use non-standard API in our design.

Using POST won't be non-standard, but requiring ETag for this to work 
might be. Here's what Bill said:

>> 3. Is it OK to require the use of ETag to distinguish CREATE and UPDATE
>> (requiring a GET operation before every UPDATE)? Or should ETag be
>> optional and used only if the system requires caching or concurrency
>> control?
>
> It is never OK to override the meaning of a header, HTTP method, or
> response code.  One of the nice things about REST is that you have a
> solid foundation of how a service behaves without ever looking at the
> documentation of that service:  This is because you know the HTTP protocol.
>
> ETag should only be used for conditional GET (when a cache is involved)
> or a conditional PUT, or POST (When concurrency is involved).

To me this means if someone installs a system and there's only one 
client using it, or any other situation where concurrency is not an 
issue, he shouldn't be required to use ETag.

-- 
Endi S. Dewata




More information about the Pki-devel mailing list