REST端点:如何正确设计对资源的操作?

时间:2018-08-02 09:55:31

标签: rest url architecture api-design restful-architecture

我的资源/contracts具有以下结构:

{
    name: "Contract name",
    signedAt: 123213231,
    // etc.
}

基本的CRUD操作非常清楚( GET /contracts GET /contracts/{id} POST {{1 }}等),当我必须对资源进行一些具体操作时,就会产生一些疑问。

以下操作之一:

  • 签署:表示合同已签署,因此/contracts日期将需要与签署合同的时刻(日期时间)一起更新。

到目前为止,我一直在考虑这些不同的方法:

匹配资源

这种方法将意味着具有以下端点方法:

补丁 signedAt

并仅发布/contracts/{id}日期signedAt,这意味着在此之后将签署合同。

我不喜欢这种方法的原因是签名日期来自客户端,我当时认为,只要签定合同,在后端初始化该日期会更好,更一致。

  

完全丢弃,因为应该在服务器上设置signedAt日期   正好在标志完成的那一刻。

发布新资源

这种方法意味着将签名动作作为资源:

POST { signedAt: 123213231 }

在这种情况下为空,因为我们不需要传递其他任何内容,因此一旦发布,后端将负责初始化签名日期。

使用“操作”发布资源

类似于先前的方法,在这种情况下,我将在合同资源上使用名为/contracts/{id}/sign的查询参数:

POST action

也有一个空的正文,其中/contracts/{idContract}?action=sign。像以前的方法一样,一旦发布后端,将负责初始化签名日期。

问题

  • 在REST API级别进行此设计的正确方法是什么?
  • 以上方法是否接近良好的设计?
  • 我需要修改任何方法吗?
  • 还有更好的选择吗?

2 个答案:

答案 0 :(得分:0)

我自己设计了一些Rest API,但我不是一个轻松的福音传教士,所以我的回答可能不是最好的。我建议采取以下措施:

  • 在REST服务中为日期值创建一个自定义转换器,该转换器接受日期和其他特定字段。例如,如果您检查Google报告API,则它们允许您使用特定的日期范围,还可以使用CURRENT_WEEK,CURRENT_MONTH等。因此,您可以添加此类特定值并使用它。例如PATCH signatureAt = CURRENT_DATE,API会正确处理。

  • 向资源添加一个布尔签名字段。用sign = true执行POST或PATCH。这样一来,您最终将可以轻松地仅查询已签名的资源;)另外,人们可能只关心是否已签名而不是已签名?

我不会使用?action = sign或/ contracts / {id} / sign,因为它们不是RESTFUL的,即使您确实使用GET和POST,您也将使用它们来创建变通方案以实现设计中应该没有动作的动作

答案 1 :(得分:0)

  

只需发布signedAt日期{signatureAt:123213231},这意味着在此之后将签署合同。

HTTP Patch

  

这组更改以一种由媒体类型标识的称为“补丁文件”的格式表示。

您可能不想考虑自己定制的媒体类型,而是要考虑一种标准格式是否合适。

例如:JSON Patch

Content-Type: application/json-patch+json

[ { "op": "replace", "path": "signedAt", "value": 123213231 } 

JSON Merge Patch是另一个合理的选择

Content-Type: application/merge-patch+json

{ signedAt: 123213231 } 

据我所知,主要区别在于JSON修补程序提供了test operation,与单纯依赖validators

相比,它提供了更好的粒度控制

但是您绝对正确-PATCH授予客户端代码权限以指定时间值。如果这不适合您的用例,则PATCH是框中错误的工具。

POST /contracts/{id}/sign
POST /contracts/{idContract}?action=sign

就REST / HTTP而言,这两个选择是等效的-您通过向不同资源发送不安全的请求来更新一种资源的状态。在resolving references时,这些拼写的行为会有一些细微的差异,但是作为请求目标,它对客户没有影响。

您似乎忽略了的一个选项:

POST /contracts/{id}

action=sign

这样做的好处是,成功后您将免费获得cache invalidation

在超媒体API中,流程可能如下所示:客户端将GET占用资源;因为尚未对资源进行签名,所以表示形式可能包括一个带有“签名”按钮的表单。表单上的操作为/contracts/{id}。消费者通过提交表单“签署”合同-代理收集表单描述的信息,将其编码到请求正文中,然后将请求发布到服务器。服务器响应成功,并且客户端的缓存知道无效先前获取的资源副本。