RESTful API和现实生活中的例子

Bur*_*jua 1 api rest restful-architecture asp.net-web-api

我们有一个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"
    },
]
Run Code Online (Sandbox Code Playgroud)

这将需要在客户端生成此json,然后将其映射到服务器上的某个模型,解析"path"属性以获取作业ID,然后执行实际取消.这对我来说似乎非常复杂和虚伪.

关于这种操作的一般建议是什么?当很多操作无法简单地映射到RESTful资源范例时,我很好奇人们在现实生活中做了些什么.

谢谢!

Dar*_*rov 6

如果通过取消作业意味着删除它,那么你可以使用DELETE动词:

DELETE /jobs?ids=123,321,...
Run Code Online (Sandbox Code Playgroud)

如果通过取消作业意味着将某个状态字段设置为取消,那么您可以使用PATCH动词:

PATCH /jobs
Content-Type: application/json
[ { "id": 123, "status": "cancelled" }, { "id": 321, "status": "cancelled" } ]
Run Code Online (Sandbox Code Playgroud)


Chr*_*mon 5

业务流程的 POST

POST在这种情况下,通常是一个被忽视的解决方案。将资源视为名词在 REST 中是一种有用且常见的做法,因此,POST 通常映射到 CRUD 语义中的“CREATE”操作——但是POSTHTTP 规范没有要求这样的事情:

POST 方法请求目标资源根据资源自身的特定语义处理请求中包含的表示。例如,POST 用于以下功能(除其他外):

  • 向数据处理过程提供数据块,例如输入到 HTML 表单中的字段;
  • 向公告板、新闻组、邮件列表、博客或类似的文章组发布消息;
  • 创建一个尚未被源服务器识别的新资源;和
  • 将数据附加到资源的现有表示。

在您的情况下,您可以使用:

POST /jobs/123/cancel
Run Code Online (Sandbox Code Playgroud)

并将其视为第一个选项的示例 - 向数据处理过程提供数据块 - 类似于使用 POST 提交表单的 html 表单。

使用这种技术,您可以返回正文中的工作表示和/或返回303 See Other位置设置为的状态代码/jobs/123

有些人抱怨这看起来“太 RPC”——但如果你阅读规范,没有什么不是 RESTful 的——我个人觉得这比试图找到从 CRUD 操作到实际业务流程的任意映射要清晰得多。

理想情况下,如果您关注遵循 REST 规范,则应通过作业表示中的超媒体链接将取消操作的 URI 提供给客户端。例如,如果您使用的是HAL,您将拥有:

GET /jobs/123
{
    "id": 123,
    "name": "some job name",
    "_links" : {
       "cancel" : {
           "href" : "/jobs/123/cancel"
       },
       "self" : {
           "href" : "/jobs/123"
       }
    }
}
Run Code Online (Sandbox Code Playgroud)

客户端然后可以获得“取消”rel 链接的href,并向它发送POST 以实现取消。

将流程视为资源

另一种选择是,根据它在您的域中是否有意义,将“取消”作为名词并将数据与其关联,例如谁取消了它,何时取消等 - 如果工作可能是,这尤其有用取消、重新打开和再次取消,因为更改历史记录可能是有用的业务数据,或者如果取消操作是一个异步过程,需要随着时间的推移跟踪取消请求的状态。通过这种方法,您可以使用:

POST /jobs/123/cancellations
Run Code Online (Sandbox Code Playgroud)

这将“创建”作业取消 - 然后您可以进行以下操作:

GET /jobs/123/cancellations/1
Run Code Online (Sandbox Code Playgroud)

返回与取消相关的数据,例如

{
    "cancelledBy": "Joe Smith",
    "requestedAt": "2016-09-01T12:43:22Z",
    "status": "in process"
    "completedAt": null
}
Run Code Online (Sandbox Code Playgroud)

和:

GET /jobs/123/cancellations
Run Code Online (Sandbox Code Playgroud)

返回已应用于作业的取消集合及其当前状态。