19212Re: [rest-discuss] URI design, part 2
- Dec 4, 2012Thank you very much for your responses Eric.
The short answer is (if I understood correctly): POST /cancel is not
REST because it lacks visibility, since it's not possible to
understand the client's intent by examining the request.
Never thought about HTTP/URI resource vs. REST resource, you say that
a URI that doesn't implement GET is probably (or always) not REST.
On Mon, Dec 3, 2012 at 1:17 PM, Eric J. Bowman <eric@...> wrote:
> 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 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
> 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.
> 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.
- << Previous post in topic Next post in topic >>