以非幂等方式更新资源的最RESTful方法是什么?

时间:2019-05-14 15:54:35

标签: rest web-applications architecture api-design

更新部分资源的最RESTful方法是什么,该资源的生成是在服务器端而不是在客户端完成的。这不是幂等操作,因为服务器上的支持数据可能在两次请求之间发生变化。

我正在创建Rest API,现在我已经确定了前进的方向。

我有一个要刷新的资源,其中包括基于支持数据创建一个大的json blob,然后将该json blob保存到数据库中,然后再提供给用户。

我的问题是,执行此操作的最RESTful方式是什么?由于客户端不执行计算,并且由于每次调用之间的数据集可能会发生变化,因此也不是幂等的,我觉得使用PUT是不自然的。

我选择了POST,但这也不正确。

第三个选择是拥有一个描述刷新操作的子资源-感觉也不正确。

例如,我有一个文档:

GET /document/<documentId>

这将返回类似的内容:

"body": {
    "createdAt": "2019-01-01 12:00:00",
    "updatedAt": "2019-01-01 13:00:00",
    "name": "example",
    "location": "example",
    "city": "example"
}

这些字段是在创建文档时由服务器生成的,客户端不会更新它们。

为了让客户端发出信号,他们希望服务器重新生成文档,我决定:

POST /document/<documentId>
"body": {
   "param1": "updatedparam1",
   "param2": "updatedparam2"
}

另一种方法是执行以下操作:

POST /document/<documentId>/refresh
"body": {...}

但这感觉更像是RPC调用,而不是REST。

从逻辑上讲这有意义吗?我没有看到很多建议,POST可以用于单一资源而不是集合。

请让我知道我是否可以扩展任何内容,我已经将头撞了一会儿,可能错过了一些东西。

1 个答案:

答案 0 :(得分:0)

  

我选择了POST,但这也不正确。

POST是fine

HTTP语义包括有关invalidating缓存的资源表示形式的规则。大概,当您告诉服务器重新生成文档时,您不想自己继续使用旧副本。因此,请求的目标uri应该与用于GET资源的URI相同。

所以:

POST /document/<documentId>

一个好的开始。

假设语义匹配,另一种方法是使用PATCH -如果您要为表示形式建议替换值,这是一个适当的选择。在这种情况下,请求的主体应为“补丁文件”。当然,您可以定义自己的补丁文档类型。通用客户可能已经了解一种或多种标准RFC-6902:JSON PatchRFC-7386:JSON Merge Patch,因此您可以通过支持一种或多种标准格式来节省一些工作。

  

我没有看到很多关于POST可以针对单个资源而不是集合的建议。

REST的部分要点是资源支持uniform interface-“单个资源”和“集合资源”看起来与相同相同。从历史上看,early specifications for POST有点不幸,它很容易被误解为CREATE。

但是普通客户不知道或不在乎您在Web表单中指定的资源是否是“集合资源”;它只是打包数据并发送请求,确信服务器将知道该怎么做。