Let's say I have a controller that takes three parameters:
class Dog {
function tell (dogId, commandId, rewardId) {
// blah
}
}
My url for accessing that might be:
mysite.com/dog/tell/1/2/3
In that case, you have to remember that the parameters map to dogId
, commandId
& rewardId
in that order. The other way to go might be something like:
mysite.com/dog/tell/1/command/2/reward/3
or for even more clarity (but probably more jiggery-pokery with your framework):
mysite.com/tell/dog/1/command/2/reward/3
Which is better? Which is more common? At first blush it seems like clearer is better. However, you still have to remember what the order of the parameters is, and now you have to remember the key-words, as well. ("Was it 'dog/command/reward' or 'command/dog/reward' or 'dog/to/for' or...?")
Thoughts? References? :)
You don't appear to be creating a RESTful API here. REST APIs use URIs to denote resources, not operations ( tell
looks like an operation to me). Operations on resources are defined by an interface that is common to all resources. I assume you're designing a REST API using HTTP, so your common interface is defined by the HTTP verbs GET, POST, PUT, DELETE, etc.
So, rather than define our service in terms of the operation tell
, lets start by thinking about a resource: dog. As a client, lets assume I'm looking for Rover the dog. My first interaction with your service might be a request like:
GET mysite.com/dogs?q=Rover
Within the response to this request, lets assume that I am given a URL of a resource that represents Rover the dog: mysite.com/dogs/3759
Now, lets find out the state of Rover the dog:
GET mysite.com/dogs/3739
In the response, I see that Rover the dog is alive, awake and standing up (ie the response tells me the state of Rover the dog). The response also includes forms which I can use to cause a transition in the state of this resource (ie the response tells me how to make Rover change state).
Now, the next step is to tell Rover to do something. We want Rover's state to transition from standing to sitting (lets assume that we can't simply update Rovers state from standing to sitting, we can only issue a command which Rover can choose to follow - just like a real dog!). Lets post a sit
command to Rover:
POST mysite.com/dogs/3739
<command name="sit"/>
We can think of the command as a resource in it's own right - it has a 'name' (sit) an issuer (me), a dog (Rover) and it may also be followed or unfollowed (depending on the dog's mood). Now in my response to this POST I get the following information
Status : 201 (Created)
Location: mysite.com/dogs/3739/commands/1299
The status tells me that this data has been received by Rover and it has caused the creation of a new resource (our command). If we want to get the state of this command, we can see it by making a request to the URL given in the Location header. Let's do that, and find out about our newly created command:
GET mysite.com/dogs/3739/commands/1299
Now the response will tell me the state of this command. Let's assume we're in luck: the command has been followed (the representation returned for this resource includes some information like followed=true
). The response also includes a link back to the resource that represents Rover (the dog to which the command was issued).
Finally, when we request the state of the resource that represents Rover:
GET mysite.com/dogs/3739
We see from the response that a state transition has occurred, and we are now told that Rover is 'sitting'. The response may also include a reference to the list of commands that Rover has been issue to-date in the form of a link to this URI:
mysite.com/dogs/3739/commands/
This is IMO much closer to a RESTful model. The domain you've chosen here may make things harder to explain and understand I think. A 'command' resource is confusing and sounds very RPC, but the word 'command' is really just used because we're talking about pets. In reality a 'command' is simply a message that you send to a dog. When we substitute the word 'command' for the word 'message', it's easier to see that a message is a resource that certainly has a state.
So in short (tl;dr):
For more reading there's a great example of RESTful interaction described here:
http://www.infoq.com/articles/webber-rest-workflow
This coffee shop example is refined and expanded upon in Jim Webber and Ian Robinson's book 'REST in Practice'.
Of course it may also be worth re-reading Fielding (section 5.2 most relevant I think):
http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm
Hard to explain in one post (sorry for the length!) but I hope this helps.
Personally, i'd prefer to have a url like mysite.com/dog/1/tell
, and pass it command=2 and reward=3 via POST. Perhaps the dog ID could be in the data too. Several reasons:
对于一个网站,我会说连接词是有用的,对于api,我说不是真的,好的文档是api所需要的。
mysite.com/tell/dog/1/command/2/reward/3
looks very much like
mysite.com/tell?dog=1&command=2&reward=3
.
In the second case, order is definitely not important. Most probably, it's not important in the first case, either. If I were you, I'd accept any combination, because it's clearly not hierarchical as URLs are expected to be. Moreover, you can't expect mysite.com/tell/dog/1
do something useful.
Since dog id, command id, and reward id only make sense together, I'd state this fact, setting the order, too:
mysite.com/tell/dog-a-command-rewarding-by/1/2/3
or even
mysite.com/tell/dog-a-command-rewarding-by/1-2-3
because you can't expect mysite.com/tell/dog-a-command-rewarding-by/1
do something useful, too.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.