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

What is the most RESTful way to update a resource in a non-idempotent way?

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

我正在创建一个 Rest API,我已经做出了一个设计选择,我非常确定前进的方向。

我有一个资源想要刷新,这涉及到基于支持数据创建一个大的 json blob,然后将该 json blob 保存到数据库中,然后再将其返回给用户.

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

我选择了 POST,但这也不合适。

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

比如我有一个文档:

GET /document/<documentId>

这会 return 类似于:

"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 可以用于单个资源而不是集合的建议。

如果我可以扩展任何内容,请告诉我,我已经为此苦苦思索了一段时间,可能遗漏了一些东西。

I settled on a POST, but that doesn't sit right either.

POST 是 fine.

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

所以:

POST /document/<documentId>

是个好的开始。

假设语义匹配,另一种方法是使用 PATCH -- that's an appropriate choice to make if what you are doing is proposing replacement values for the representation. In that case, the body of the request should be a "patch document". You can, of course, define your own type of patch document; generic clients may already understand one or more of the standards RFC-6902:JSON Patch or RFC-7386:JSON Merge Patch,这样您就可以通过支持一种或多种标准格式来节省一些工作。

I haven't seen many suggestions that POST can be to a single resource as opposed to a collection.

REST 的部分要点是资源支持 uniform interface - "single resources" and "collection resources" look the same. Historically, we got a bit unlucky with the early specifications for POST,这很容易被误解为 CREATE。

但是一般客户不知道,也不关心您在网络表单中指定的资源是否是“集合资源”;它只是打包数据并发送请求,相信服务器会知道该做什么。