Re: URI design, part 2

"Eric J. Bowman" <[email protected]>
Newsgroups gmane.comp.web.services.rest
Organization Bison Systems Corporation
Message-ID <[email protected]>
Max Toro wrote:
>
> > Well, what are you expecting to GET from /cancel, or are you just
> > using that URL to invoke a procedure? If so, then there are a few
> > places Roy's thesis admonishes against it in Chapter 6 -- the rest
> > of REST is about positive, rather than negative, reinforcement of
> > the identification of resources constraint. Suggested reading:
> > 6.5.2; 6.2.1, in particular: "REST [defines] a resource to be the
> > semantics of what the author intends to identify."
> 
> To clarify, /orders/1/cancel is used to modify a resource, using POST.
> A GET request would result in a Method Not Allowed response.
> 

Yes, such examples are out there, but in them, /cancel is NOT a resource
in the REST sense so they must be some style of RPC... REST, not so
much. Representational State Transfer means just that -- resources are
manipulated by transferring representations of their current, intended,
desired etc. state.  Chapter 5.4:

"Requests and responses have the appearance of a remote invocation
style, but REST messages are targeted at a conceptual resource rather
than an implementation identifier."

This example is a REST anti-pattern, as I cannot deduce the current
(sub)state of the order (active or canceled) by dereferencing the URL
I'm given for manipulating that (sub)state. Just making a toggle POST
also fails to transfer any representation of anything, let alone
application state, and isn't proper HTTP (which can never be proper
REST).

REST isn't about optimizing upstream traffic, it's about optimizing GET.
What advantage does a subresource give when it contains no content from
the parent resource?  My goal with subresources is to increase the cache
stickiness of their parent resources.  Replace the subresource content
in the parent resource, with a link or a hypertext control linked to the
subresource.  The link or hypertext control remains static, and cached,
as the content of the subresource varies.

That's a RESTful pattern, as the subresource now has a representation
(other than that of the 406 error) we can transfer and manipulate to
effect change of the parent resource.

> 
> > Not the semantics of a method invocation.  What does /cancel
> > identify? Sounds to me like a method of tunneling DELETE through
> > POST which identifies nothing, iow a procedure endpoint, which is
> > characteristic of various styles but not of the REST style.  The
> > hypertext constraint only makes sense if your resources make sense,
> > in that their URLs are identifiers rather than endpoints.
> 
> If I understand correctly, you are saying that if I need to affect a
> resource then I should use the uniform interface on that resource URI,
> and not another URI.
> 

Absolutely not!  My example changed /order/1 by manipulating /order/1
/status.  The /order/1 resource includes its status, but its 200 OK
representations only include links to the /status subresource, derived
from the /order/1 resource such that manipulating a representation
of /order/1/status updates /order/1 (on the server, you can do anything
you want; on the client, the cached link/control in /order/1 now returns
a different value).

There's no cost to adding a URI like this, nor does it preclude changing
order status via PUT/PATCH to /order/1.  The difference is that /status
uses REST's uniform interface, unlike /cancel.  The /order/1/status URL
is only presented within a hypertext control which explains how to
manipulate it -- picture a drop-down list with the current status
highlighted, meeting the hypertext constraint.  You can always GET the
status of an order even if you don't have a copy of that order, a
useful separation of concerns beyond just optimizing GET, promoting
serendipitous re-use.

>
> > Which brings us to Chapter 5, and the short answer to your question:
> > "POSTing to /cancel violates the Identification of Resources
> > constraint, and is therefore unRESTful."  But I've found that just
> > giving that answer tends to upset folks who've only read Chapter 5,
> > then they get defensive about why can't they call their API
> > RESTful, accusations of pedantry follow, and threads devolve into
> > general ugliness, heheh...
> 
> After reading that chapter again I'm not sure my example violates
> anything, but I'd love to get more clarification from you. Is it the
> use of a verb in the URI? or not using the URI of the resource I'm
> trying to modify directly?
>

The biggest problem, is that an RPC endpoint which has no GET function
while improperly listening for a method itself as a trigger rather than
taking action based on the content of the entity required by that method
and in obeyance of the semantics of that method, is so far away from
REST that I don't know where to start except by urging that Roy's
thesis be read in its entirety.  Because it's obvious to me that this
violates the first three uniform interface constraints, making adherence
to the fourth irrelevant:

"REST is defined by four interface constraints: identification of
resources; manipulation of resources through representations; self-
descriptive messages; and, hypermedia as the engine of application
state."

Note that "noun/verb" terminology is not present in the dissertation.
But, yeah, if your URI is a "verb" you're probably getting REST wrong.
There is no "cancel" method in the uniform interface.  There are two
basic means of solving this -- one, is refactor your cancel operation
to use DELETE; two, tunnel your proprietary cancel method through POST.

http://tech.groups.yahoo.com/group/rest-discuss/message/19210

Making this operation its own URI doesn't make it more RESTful, as the
resulting URI is only a resource in the HTTP/URI sense, but not the
REST sense, of the term.  Utilizing subresources to break out more
dynamic aspects of content and cache them separately is RESTful; if the
contents of the GET are also allowable content of a PUT then we're
letting hypertext drive application state instead of listening for POST
events to trigger server-object methods we've failed to refactor to the
uniform REST interface.

-Eric
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.