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: > > 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. > I'd phrase it differently: "POST /cancel violates self-descriptiveness as user intent cannot be discerned by examining the request." This would hold true even if GET /cancel had a 200 OK response. Even that's oversimplifying in that part of the reason POST is wrong here, is because DELETE is right. But, no, I do not believe setting up an URL to listen for POST and taking action not based on anything in the POST request, is ever an example of the REST style, regardless of the nature of the resource. My real short answer is, "POST /cancel doesn't use REST's uniform interface." Neither is it an example of the REST style for POST to have a definition which varies by resource, iow sometimes it works without an entity (method-tunnel listener), sometimes it doesn't (create resource); even if hypertext-driven, such nonstandard method usage inevitably results in coupling between client and server, instead of relying on shared understanding of standardized method semantics. Fixing the POST to have an entity that's ignored might make it valid HTTP and solve this, but it still wouldn't be an example of the REST style, where the requested state change is transferred in the entity (with a few exceptions) -- not defined per resource by the method being tunneled through / triggered by POST. Conceptually, it still violates the identification of resources constraint, which is why it isn't visible regardless of how we implement it in terms of hypertext or method selection. Using the uniform interface means refactoring internal methods like 'cancel' to fit the resource/representation model of REST such that the request methods and response codes used map generically to those of your chosen protocol. Assigning them URIs to toggle with semantically-void messages is simply some other style not encompassed by REST's uniform interface constraint, not something that's superficially fixable by improving visibility or adding a 200 OK response. > > 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. > More like, "REST resources are concepts, not actions." Just using URIs doesn't bestow compliance with the identification of resources constraint upon a system, it's more nuanced than that. I can't imagine why a bona-fide REST resource would ever deliberately fail to have a retrieval mapping, no. I think the more important takeaway is method selection. We have DELETE in order to avoid such convoluted POST-based cancel mechanisms. It isn't RESTful to use POST when another method's semantics happen to closely describe user intent. From Roy's blog: "POST only becomes an issue when it is used in a situation for which some other method is ideally suited: e.g., retrieval of information that should be a representation of some resource (GET), complete replacement of a representation (PUT), or any of the other standardized methods that tell intermediaries something more valuable than 'this may change something.' The other methods are more valuable to intermediaries because they say something about how failures can be automatically handled and how intermediate caches can optimize their behavior. POST does not have those characteristics, but that doesn't mean we can live without it. POST serves many useful purposes in HTTP, including the general purpose of 'this action isn't worth standardizing.'" http://roy.gbiv.com/untangled/2009/it-is-okay-to-use-post Since DELETE is inherently self-descriptive of user intent to cancel an order, and is already "listened for" rather than requiring an entity be transferred, and has inherent idempotency matching the inherently idempotent user intent captured by a cancel request, DELETE must be the proper method for implementation using HTTP. Now, maybe your media type doesn't support DELETE, in which case contriving a /cancel URI may very well be called for until such time as it does. I won't fault anyone for doing this out of pragmatism, so long as they understand it as a mismatch, inconsistent with the architectural style they're following. REST is a tool which allows you, over time, to make improvements to the architecture you have in accordance with an idealized model. To me, accepting mismatches for what they are, is far more useful than coming up with convoluted explanations for why they aren't, for the sake of buzzword compliance. Change is easier when it's based on having been right all along, rather than based on having to admit error. ;-) -Eric