This discussion on whether verbs should be used in URIs is excellent!
Thanks Joe for raising this issue. It has certainly stimulated new
ideas and questions in my mind. Let's not let this discussion stop
until we have fully explored all facets of this issue and have arrived
at consensus. I think that it is important that we (the REST community)
speak with a unified voice.
Let me try to first summarize the issue and both sides of the argument.
Then I will add my own thoughts on the topic.
The issue is this: should a URL be allowed to have verbs in it?
Example. Here's an example of a URL that contains a verb (add-to-cart)
http://www.parts-depot.com/parts/00345/add-to-cart
Let's now summarize both sides of this issue
The Nouns-Only Camp
This side of the argument says that URLs should only contain nouns.
They say that verbs should not be allowed in URLs. Here's why:
1. By definition, resources are "things" not "actions". URLs identify
resources, not functions.
2. Separation of concerns: keep the identification (i.e., the URL) of a
resource separate from the methods (HTTP GET, POST, PUT, DELETE) applied
to the resource. In OO terms we might think of the URL as providing the
name of the Object, and the HTTP methods as the generic set of methods
on the Object. For example:
{http://www.parts-depot.com/parts/00345}.GET()
3. Generic interface: keep the interface to resources generic - the HTTP
methods. When you allow verbs then you are essentially expanding the
interface. For example:
http://www.parts-depot.com/parts/00345/add-to-cart
is essentially a composition of methods:
{{http://www.parts-depot.com/parts/00345}.add-to-cart()}.GET()
Thus, the resource (part 00345) is exposing an implementation function,
add-to-cart.
The Verbs-Allowed Camp
This side of the argument says that URLs should be allowed to contain
verbs as well as nouns. Here's why:
1. It seems natural that you would want to identify a resource and tell
it to take an action. Some examples:
http://www.my-home.org/air-conditioning/onhttp://www.google.com/search?topic="juice-machines"
2. Verb-oriented URLs are very program-friendly. For example, a program
to control devices in my house might look like this:
http://www.my-home.org/connect-to-central-computerhttp://www.my-home.org/air-conditioning/onhttp://www.my-home.org/air-conditioning/adjust-temp?value=68http://www.my-home.org/stereo/onhttp://www.my-home.org/stereo/play-cd?cd=Timeless-Serenity
3. Unilaterally prohibiting functions as URI-accessible makes the Web
less friendly and useable, as I will need to contort things to get
around this constraint. Imagine doing the above using just nouns.
Is this a fair summary of both sides? If not, please add/correct.
Now for my own comments:
As always, I think best with a concrete example in front of me. So,
let's consider Parts Depot. This company has deployed some Web services
to enable clients to:
1. Get a list of parts
2. Get detailed information about a part
3. Purchase parts
It is the third service (purchase parts) which is most relevant to this
discussion.
Let's suppose that the client has used the first service to get the
parts list, and then used the second service to drill down to get
detailed information about part 00345. Suppose that this is the
response:
<?xml version="1.0"?>
<p:Part xmlns:p="http://www.parts-depot.com"
xmlns:xlink="http://www.w3.org/1999/xlink">
<Part-ID>00345</Part-ID>
<Name>Widget-A</Name>
<Description>
This part is used within the frap assembly
</Description>
<Specification
xlink:href="http://www.parts-depot.com/parts/00345/specification"/>
<UnitCost currency="USD">0.10</UnitCost>
<Quantity>10</Quantity>
</p:Part>
Suppose that the client decides that he/she wants to "add this to
his/her shopping cart". To provide this capability Parts Depot may
provide another element <AddToCart> when it returns detailed part
information. Thus, instead of the above XML document the client would
receive this:
<?xml version="1.0"?>
<p:Part xmlns:p="http://www.parts-depot.com"
xmlns:xlink="http://www.w3.org/1999/xlink">
<Part-ID>00345</Part-ID>
<Name>Widget-A</Name>
<Description>
This part is used within the frap assembly
</Description>
<Specification
xlink:href="http://www.parts-depot.com/parts/00345/specification"/>
<UnitCost currency="USD">0.10</UnitCost>
<Quantity>10</Quantity>
<AddToCart href="http://parts-depot.com/parts/00345/add-to-cart"/>
</p:Part>
Note the last element, <AddToCart href="..."/>. The URL in the href
attribute:
http://parts-depot.com/parts/00345/add-to-cart
clearly contains a verb, add-to-cart.
I have a couple of thoughts about this design:
1. If the HTTP method for the above URL is GET then it is violating the
principle that all GETs should be side-effect free.
2. One of the principles of REST is that the client should maintain
his/her own state. The server should not do so. The above approach has
the server maintaining state about the client.
Here's an alternative solution. The client creates a Purchase Order
(PO) which identifies the parts he/she is interested in purchasing.
When the client finds a part that he/she is interested in, the client
will add that part number to the PO. When the client is ready he/she
submits the PO. Some things to note:
1. The PO represents the "shopping cart".
2. The PO is composed on the client side, not the server side.
This second design seems to be more in the spirit of REST.
Those are the two ways that I see for implementing the purchase parts
Web service. Are there other (better) ways? Any comments? /Roger
This discussion on whether verbs should be used in URIs is excellent! Thanks Joe for raising this issue. It has certainly stimulated new ideas and questions...
Roger L. Costello
costello@...
Jun 15, 2002 2:52 pm
Here's an alternate view of purchasing that might make the resource view more clear (and more like nouns): There are at least two stages of purchasing on the...
... The one I've seen used most often (mostly on contract agreements before downloading, not purchasing) is when a POST button is selected to agree, and then...
Mark Baker
distobj@...
Jun 17, 2002 6:38 pm
... I'm not sure where my version of this verb/URI issue stands, but here is the way I have designed it in my own efforts. As I mentioned before, I have a ...
... method? ... things ... I know. I'm afraid I expressed my question very badly. I should have written "is there a pattern for how Web sites usually handle...
... I guess the basic question is whether you *need* method objects. A REST-purist view would be that you should use methods as an implementation technique to...
... My question was "what are you posting to?" and that's where I came up with the idea of creating method resources, which have URIs (if they are published),...
I'm struggling to catchup with rest-discuss, but found one point I wanted to respond to, only to lose the message. Basically, somebody was looking for an API...
Mark Baker
distobj@...
Jun 17, 2002 5:33 pm
... I would love to hear more detail on your experiences using this API wrt REST I have been keeping tabs on Cocoon (http://xml.apache.org/cocoon/) as a...
Robert Leftwich
robert@...
Jun 18, 2002 12:07 am
... I've worked with Cocoon a fair bit recently, there are 3 tutorials on developerWorks that I wrote if you want some more background on it. I've been...
... We Cocoon a lot here, and it can accept XML documents in a POST. The one thing that is nice about Cocoon is the sitemap, which is a mapping of logical...
... Servlet v2.x also has doDelete() and doPut(). Cocoon requires v2.2 so it should be able to be supported, but I don't know to what extent it actually is...
Robert Leftwich
robert@...
Jun 19, 2002 6:09 pm
Hi Roger, I'm not sure that there is sufficient disagreement here to warrant "camps" in this discussion, but as usual, you've done a great job summarizing the ...
Joe Hsy
joe.hsy@...
Jun 16, 2002 7:24 am
... You've identified two resources - what part tells it to take an action? and what action does it take? http://www.my-home.org/air-conditioning/on could test...
... application ... For me, those example are not 'natural', they are merely 'procedural'. A noun/object/resource based approach isn't any more natural either...
... I think that they vary widely. I think that after you do all of the negotiation and credit card stuff you should just have a "click here to download your...
... That doesn't seem very smart from a business perspective. You're talking about an information product being sold for money, right? What's to stop me from...
... Ah ... you're right. Nonetheless, I see a lot of businesses obfuscating URIs or creating them for each (business) transaction, presumably so that people...
... Well I did say that the download URI and license URI would usually be separate. By license URI I meant a license key that makes the download work. That key...
... From: S. Mike Dierken [mailto:mdierken@...] ... I agree that what is "natural" is often a matter of opinion. And I certainly don't view these as...
Joe Hsy
joe.hsy@...
Jun 17, 2002 8:25 pm
... From: Philip Eskelin [mailto:philip@...] ... the ... published), can ... and ... This is very cool and is very much what I was getting at. I can't...
Joe Hsy
joe.hsy@...
Jun 18, 2002 8:43 am
... Yes, I agree with you. This is a concern of mine, and one of the reasons I've asked the group about their thoughts on it. What I really wanted to do was ...
... Yes. What you and Joe have been discussing is not REST, it's RPC with the method in the URI rather than in the body. With REST, a common way of ordering a...
Mark Baker
distobj@...
Jun 18, 2002 4:59 pm
For this example, and to make it more RESTful, I would change it to this... ... NEW: Order order = new Order("http://www.parts-depot.com/orders/32432"); ...
... Got it. I see the difference. ... This is something that will also apply to my topic and queue abstractions. For example, when you publish to a topic,...
As a side note, in HTTP you can provide a header like : content-disposition: attachment; filename=suggested_name.ext for content-types other than octet-stream...
... From: Seth Ladd [mailto:seth@...] ... I don't think calling methods and transferring state are necessarily mutually exclusive. Calling a method is a...