假设我有一个控制器,它有三个参数:
class Dog {
function tell (dogId, commandId, rewardId) {
// blah
}
}
我访问的网址可能是:
mysite.com/dog/tell/1/2/3
在这种情况下,您必须记住参数映射到dogId
,commandId
&按此顺序rewardId
。另一种方式可能是:
mysite.com/dog/tell/1/command/2/reward/3
或者为了更清晰(但可能更多的jiggery-pokery与您的框架):
mysite.com/tell/dog/1/command/2/reward/3
哪个更好?哪个更常见?乍一看似乎更清晰更好。但是,您仍然需要记住参数的顺序,现在您还必须记住关键字。 (“是'狗/命令/奖励'还是'命令/狗/奖励'或'狗/到/为'或......?”
思考?参考文献? :)
答案 0 :(得分:4)
您似乎没有在此处创建RESTful API。 REST API使用URI来表示资源,而不是操作(tell
看起来像是对我的操作)。资源操作由所有资源共有的接口定义。我假设您正在使用HTTP设计REST API,因此您的公共接口由HTTP动词GET,POST,PUT,DELETE等定义。
因此,我们不是根据操作tell
来定义我们的服务,而是从思考资源开始:狗。作为一个客户,让我们假设我正在寻找罗孚狗。我与您的服务的第一次互动可能是以下请求:
GET mysite.com/dogs?q=Rover
在对此请求的回复中,我们假设我获得了一个代表Rover狗的资源的URL:mysite.com/dogs/3759
现在,让我们找出罗孚狗的状态:
GET mysite.com/dogs/3739
在回答中,我看到罗孚狗还活着,醒着站起来(即响应告诉我罗孚狗的州)。响应还包括我可用于导致此资源状态转换的表单(即响应告诉我如何使Rover更改状态)。
现在,下一步是告诉罗孚做点什么。我们希望罗孚的状态从站立转变为坐着(假设我们不能简单地更新流浪者状态从站立到坐着,我们只能发出一个罗孚可以选择遵循的命令 - 就像一只真正的狗!)。让我们向Rover发布sit
命令:
POST mysite.com/dogs/3739
<command name="sit"/>
我们可以将命令视为资源本身 - 它有一个'名字'(坐着)发行人(我),一只狗(流浪者),它也可能被跟随或取消跟踪(取决于狗的心情)。现在,在我对此POST的回复中,我得到以下信息
Status : 201 (Created)
Location: mysite.com/dogs/3739/commands/1299
状态告诉我Rover已收到此数据,并导致创建新资源(我们的命令)。如果我们想获得此命令的状态,我们可以通过对Location头中给出的URL发出请求来查看它。让我们这样做,并找出我们新创建的命令:
GET mysite.com/dogs/3739/commands/1299
现在响应会告诉我这个命令的状态。让我们假设我们很幸运:已经遵循了命令(为此资源返回的表示包括一些信息,如followed=true
)。响应还包括一个返回资源的链接,该资源代表Rover(发出命令的狗)。
最后,当我们请求代表Rover的资源状态时:
GET mysite.com/dogs/3739
我们从回应中看到状态转变已经发生,我们现在被告知罗孚是“坐着”。响应还可能包括对Rover迄今为止以此URI链接形式发布的命令列表的引用:
mysite.com/dogs/3739/commands/
这是IMO更接近RESTful模型。你在这里选择的域名可能会让我更难以解释和理解。 “命令”资源令人困惑,听起来非常冗余,但“命令”这个词实际上只是因为我们谈论的是宠物。实际上,“命令”只是您发送给狗的消息。当我们用“命令”这个词替换“消息”这个词时,就会更容易看到一条消息是一个肯定有状态的资源。
简而言之(tl; dr):
如需更多阅读,这里有一个很好的RESTful交互示例:
http://www.infoq.com/articles/webber-rest-workflow
这个咖啡店的例子在Jim Webber和Ian Robinson的书“REST in Practice”中得到了完善和扩展。
当然,重新阅读菲尔丁也是值得的(我认为第5.2节最相关):
http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm
很难在一篇文章中解释(抱歉篇幅!)但我希望这会有所帮助。
答案 1 :(得分:1)
就个人而言,我更喜欢拥有像mysite.com/dog/1/tell
这样的网址,并通过POST传递命令= 2和奖励= 3。狗ID可能也在数据中。
有几个原因:
答案 2 :(得分:0)
对于一个网站,我会说连接词是有用的,对于api,我说不是真的,好的文档就是api所需要的。
答案 3 :(得分:0)
mysite.com/tell/dog/1/command/2/reward/3
非常像
mysite.com/tell?dog=1&command=2&reward=3
。
在第二种情况下,订单绝对不重要。最有可能的是,它在第一种情况下也不重要。如果我是你,我会接受任何组合,因为它显然不是层次结构,因为URL是预期的。此外,您不能指望mysite.com/tell/dog/1
做一些有用的事情。
由于狗ID,命令ID和奖励ID只能一起使用,我也会说明这个事实,设定顺序:
mysite.com/tell/dog-a-command-rewarding-by/1/2/3
甚至
mysite.com/tell/dog-a-command-rewarding-by/1-2-3
因为你不能指望mysite.com/tell/dog-a-command-rewarding-by/1
做一些有用的事情。