On Sat, 2013-06-29 at 16:12 -0500, Endi Sukma Dewata wrote:
On 6/29/2013 2:16 PM, Ade Lee wrote:
> One thing I just noticed though is the operation to add a token.
> You have POST /tokens passing in the tokenId.
>
> POST /tokens is only used when creating a resource when the URL of the
> resource is unknown -- ie. it will be specified by the server. An
> example of this is POST /certrequests which returns the URL of the
> request /certrequests/0xf00 where 0xf00 is the request ID as assigned by
> the server.
That is one way to use POST, but in general it doesn't always have to be
that limited. Consider the ID as an optional parameter. You can specify
it, but it's not specified the server could generate a new ID
automatically (not that we want to do that for this case). For the
client it would be easier to use the same operation to create a new
entry, with or without the ID. The operation that will work for both
cases is POST-ing into the collection.
I don't think this is violating any REST guidelines. It's also
consistent with the add operation for the existing user and group resources.
Maybe we need to revisit these then.
> In this case, the token ID is what is being passed in. So we know the
> resultant URL when the resource is created. There are two options
> instead:
>
> a) PUT /tokens/tokenID
> b) POST /tokens/tokenID
>
> My preference is a) but of course the advantage of (b) is that there is
> a distinction between an ADD and a modify operation.
>
> The same comment applies to all the ADD operations in the design.
The problem with (a) is that without ETag there's a risk overwriting an
existing token, and there's no warning or error message when that
happens. While ETag is desired, it should be optional (can we guarantee
all clients will support ETag?) and may not get implemented right away.
If we POST to the collection the server can reject it if the entry
already exists. Also, naturally an add operation is not idempotent, so
we should not use PUT.
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.
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.
Just because we may not implement etags in the first iteration does not
mean that we should use non-standard API in our design.
Option (b) is a little weird because usually we expect the resource
would already exist when we POST. POST-ing to the collection is fine
because the collection always exists.
I agree that option (b) is weird.