一段时间以来,我一直在阅读有关 RESTful 服务的文章,并且我了解对 RESOURCES 使用 VERBS 的重要性。
但有一件事我无法理解。如果我们需要调用不属于 CRUD 的某个操作,会发生什么?
例如,考虑我想让猫跳。我们应该使用哪种格式?
以下是 RESTful 吗?
http://host/cats/123/jump
一段时间以来,我一直在阅读有关 RESTful 服务的文章,并且我了解对 RESOURCES 使用 VERBS 的重要性。
但有一件事我无法理解。如果我们需要调用不属于 CRUD 的某个操作,会发生什么?
例如,考虑我想让猫跳。我们应该使用哪种格式?
以下是 RESTful 吗?
http://host/cats/123/jump
如果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
带有主体(动作类型在 request 中定义:
{
"actionType": "jump",
"customActionParameter": "some value"
}
但这将是一个矫枉过正。所以我发现遵循Google Api Design Guide for Custom Methods更容易:
POST /cats/123:jump
这是谷歌在其云基础设施 Api 中使用的方法
不要将 HTTP 动词与您域的状态机转换或操作混为一谈。
Stripe 的发票工作流程提供了一个很好的示例,说明如何以一种安静的方式表示状态转换或域操作。
您的域模型上的操作很可能通过对状态或状态字段的修改(PUT 或 PATCH)来表示,这将触发您自己代码的状态机中的工作流。例如,在您的示例中,跳跃动作也可能导致与 3x 步数相同的状态,因此它可能是对高度或高度字段的修改。然后,您的代码可能会实现某种类型的工作流管理或状态机,然后您可以根据请求的状态更改发出自己的事件和验证规则,而不是基于为实现它而执行的“操作”。
游戏晚了,但是因为 REST 是关于你的资源的状态,如果有点冗长,这也是可以接受的。这用形容词或名词替换了动词(正如@developerjack 所指出的,它经常与 HTTP 动词混为一谈)。
对于有限的一组自然状态,这种语法可能更有意义。例如,使用调度程序,我以前做过: