【发布时间】:2012-04-23 11:07:54
【问题描述】:
一段时间以来,我一直在阅读有关 RESTful 服务的文章,并且我了解对 RESOURCES 使用 VERBS 的重要性。
但有一件事我无法理解。如果我们需要调用不属于 CRUD 的某个操作会发生什么?
例如,假设我想做一只猫跳。我们应该使用哪种格式?
以下是 RESTful 的吗?
http://host/cats/123/jump
【问题讨论】:
标签: web-services rest uri
一段时间以来,我一直在阅读有关 RESTful 服务的文章,并且我了解对 RESOURCES 使用 VERBS 的重要性。
但有一件事我无法理解。如果我们需要调用不属于 CRUD 的某个操作会发生什么?
例如,假设我想做一只猫跳。我们应该使用哪种格式?
以下是 RESTful 的吗?
http://host/cats/123/jump
【问题讨论】:
标签: web-services rest uri
如果cats/123 代表一个资源,那么可以这样想:该资源可以有许多 状态(吃、走、睡、跳跃、小便、.. .)。当您使用 REST 架构风格设计 API 时,您希望允许客户端应用程序向将更改其状态的资源发出允许的请求。
在cats/123 的上下文中,您可以通过一系列将导致资源状态更改的POST 请求来执行此操作。利用 REST 中的超媒体功能,您可以创建如下所示的请求和响应流程。请注意,允许的链接会随着对 POST 的响应而改变。此外,客户端应用程序将编码到 Links 数组中包含的属性,而不是 Href 属性中包含的实际 URI。
请求:
GET cats/123
回复:
{
"Color" : "black",
"Age" : "2",
"Links":[
{
"Food":"kibbles",
"Method":"POST",
"Href":"http://cats/123",
"Title":"Feed the cat"
},
{
"Scare":"yell real loud",
"Method":"POST",
"Href":"http://cats/123",
"Title":"Scare the cat"
}]
}
请求:
POST cats/123
{
"Food":"kibbles"
}
回复:
{
"Color" : "black",
"Age" : "2",
"Tummy" : "full"
"Links":[
{
"Sleep":"lap",
"Method":"POST",
"Href":"http://cats/123",
"Title":"Pet the cat"
},
{
"Scare":"yell real loud",
"Method":"POST",
"Href":"http://cats/123",
"Title":"Scare the cat"
}]
}
【讨论】:
对于纯粹的 Restful 设计,我会推荐类似的东西:
POST /cats/123/actions
带有主体(动作的类型在请求中定义:
{
"actionType": "jump",
"customActionParameter": "some value"
}
但这将是一个矫枉过正。 所以我发现关注Google Api Design Guide for Custom Methods 更容易:
POST /cats/123:jump
这是谷歌在其云基础设施 API 中使用的方法
【讨论】:
/cats/123/jumps。想想 ID 为 123 的猫的跳跃。
不要将 HTTP 动词与您域的状态机转换或操作混为一谈。
Stripe 的 invoice workflow 提供了一个很好的示例,说明如何以一种安静的方式表示状态转换或域操作。
您的域模型上的操作很可能通过对状态或状态字段的修改(PUT 或 PATCH)来表示,这将触发您自己代码的状态机中的工作流。例如,在您的示例中,跳跃动作也可能导致与 3x 步数相同的状态,因此它可能是对高度或高度字段的修改。然后,您的代码可能会实现某种类型的工作流管理或状态机,然后您可以根据请求的状态更改发出自己的事件和验证规则,而不是基于为实现它而执行的“操作”。
【讨论】:
游戏晚了,但是因为 REST 是关于资源状态的,所以这也是可以接受的,如果有点冗长的话。这用形容词或名词替换了动词(经常与@developerjack 指出的 HTTP 动词混为一谈)。
这种语法对于有限的自然状态集可能更有意义。例如,我以前做过这样的调度程序:
【讨论】: