我们有一个Web应用程序(AngularJS和Web API),它具有非常简单的功能 - 显示作业列表,并允许用户选择和取消所选作业。
我们正在尝试使用我们的API遵循RESTful方法,但这会让人感到困惑。
轻松获得工作 - 简单GET: /jobs
我们如何取消所选择的工作?请记住,这是我们需要实施的唯一作业。最简单和最合乎逻辑的方法(对我而言)是将所选作业ID的列表发送到API(服务器)并执行必要的过程。但那不是RESTful方式。
如果我们要按照RESTful方法进行操作,那么我们需要将PATCH请求发送到jobs
,并使用与此类似的json:
PATCH: /jobs
[
{
"op": "replace",
"path": "/jobs/123",
"status": "cancelled"
},
{
"op": "replace",
"path": "/jobs/321",
"status": "cancelled"
},
]
这将需要在客户端生成此json,然后将其映射到服务器上的某个模型,解析"path"
属性以获取作业ID,然后执行实际取消。这对我来说似乎非常复杂和虚伪。
关于此类操作的一般建议是什么?我很好奇人们在现实生活中做了多少事情,而很多操作都不能简单地映射到RESTful资源范例。
谢谢!
答案 0 :(得分:6)
如果通过取消作业表示删除它,那么您可以使用DELETE
动词:
DELETE /jobs?ids=123,321,...
如果通过取消作业表示将某些状态字段设置为已取消,则可以使用PATCH
动词:< / p>
PATCH /jobs
Content-Type: application/json
[ { "id": 123, "status": "cancelled" }, { "id": 321, "status": "cancelled" } ]
答案 1 :(得分:4)
POST
通常是一个被忽视的解决方案。将资源视为名词在REST中是一种有用且常见的做法,因此,POST通常映射到CRUD语义的“CREATE”操作 - 但是HTTP Spec for POST不强制要求这样做:
POST方法请求目标资源根据资源自身的特定语义处理请求中包含的表示。例如,POST用于以下功能(以及其他功能):
- 向数据处理流程提供数据块,例如输入HTML表单的字段;
- 在公告栏,新闻组,邮件列表,博客或类似文章组中发布消息;
- 创建尚未由源服务器识别的新资源;和
- 将数据附加到资源的现有表示中。
在您的情况下,您可以使用:
POST /jobs/123/cancel
并将其视为第一个选项的示例 - 为数据处理过程提供数据块 - 类似于使用POST提交表单的html表单。
使用此技术,您可以在正文中返回作业表示和/或返回303 See Other
状态代码,并将位置设置为/jobs/123
有些人抱怨这看起来“过于冗余” - 但如果你阅读规范,那么没有什么不是RESTful的 - 而且我个人觉得它比尝试从CRUD操作到实际业务的任意映射要清楚得多过程
理想情况下,如果您关注遵循REST规范,则应通过作业表示中的超媒体链接将取消操作的URI提供给客户端。例如如果您使用的是HAL,则需要:
GET /jobs/123
{
"id": 123,
"name": "some job name",
"_links" : {
"cancel" : {
"href" : "/jobs/123/cancel"
},
"self" : {
"href" : "/jobs/123"
}
}
}
然后客户端可以获取“取消”rel链接的href,并向其发送POST以实现取消。
另一种选择是,取决于你的域名是否有意义,使名词“取消”并将数据与其关联,例如谁取消它,何时取消等等 - 这在以下情况下特别有用作业可能会被取消,重新打开和取消,因为更改历史记录可能是有用的业务数据,或者取消行为是一个需要跟踪取消请求状态的异步过程。使用这种方法,您可以使用:
POST /jobs/123/cancellations
将“创建”取消作业 - 然后您可以执行以下操作:
GET /jobs/123/cancellations/1
返回与取消相关的数据,例如
{
"cancelledBy": "Joe Smith",
"requestedAt": "2016-09-01T12:43:22Z",
"status": "in process"
"completedAt": null
}
和
GET /jobs/123/cancellations
返回已应用于作业及其当前状态的取消集合。
答案 2 :(得分:0)
示例1:让我们将其与一个真实的示例进行比较:您去一家坐在餐桌旁的餐厅,然后选择需要ABC。您将让您的服务员上来并记下您想要的东西。你告诉他你要ABC。因此,您正在请求ABC,服务员用ABC回复,他进入厨房为您提供食物。在这种情况下,服务员是您和厨房之间的接口。将请求从您那里带到厨房是他的责任,请确保它已完成,并且您知道准备就绪后,他会作为答复回覆您。
示例2:我们可以关联的另一个重要示例是旅行预订系统。例如,以独木舟为最大的票务在线网站。输入目的地后,选择日期并单击搜索,您得到的是不同航空公司的结果。皮划艇如何与所有这些航空公司通信?这些航空公司实际上必须以某种方式向皮划艇公开某些信息。就是这么多,都是通过API的
示例3:现在打开UBER看看。网站加载后,您便可以登录或继续使用Facebook和Google。在这种情况下,Google和Facebook也会公开一定程度的用户信息。 UBER与Google / Facebook之间已经达成了一项协议。这就是让您注册Google / Facebook的原因。
答案 3 :(得分:-2)
PUT /jobs{/ids}/status "cancelled"
所以例如
PUT /jobs/123,321/status "cancelled"
如果要取消多个作业。请注意,作业ID不得包含逗号字符。