修补 collection 时响应 body

Response body when PATCHing a collection

在我的 REST 中 API 我有一个非常大的 collection;它包含数百万个项目。这个 collection 的路径是 /mycollection

因为这个 collection 太大,所以 GET 整个 collection 不是好的做法,所以 API 支持分页。分页将是获取 collection

的主要方式
GET /mycollection?page=1&page-size=100 HTTP/1.1

假设原始 collection 包含 1,000,000 个项目,我想更新 5,000 个,删除 3,000 个并添加 2,000 个项目。我可以编写 API 来支持通过 PUT 方法或 PATCH 方法更新 collection。虽然这两种方法都需要非常不同的请求主体,但我相信这两种方法都需要完全相同的响应 body,即响应 body 必须包含整个更新资源的当前表示,即所有 999,000 个项目在 collection.

正如我之前提到的 GET 整个 collection 是不现实的;这个太大了。出于同样的原因,我不想 PUTting 或 PATCHing 到 return 整个 collection。将查询参数添加到 PUTPATCH 请求也不起作用,因为 PUTPATCH 都不是安全方法。

那么在这个大 collection 场景中正确的反应是什么?

我可以回复

HTTP/1.1 202 Accepted
Location: /mycollection?page=1&page-size=100

202 Accepted 响应代码感觉不正确,因为更新应该是同步完成的。 Location header 也不太对劲。我也许可以选择 Links header,但感觉还是不对。

我再问一次,在这个大 collection 场景中,正确的反应是什么?

这个问题是基于一个误解:

While either method would require very different request bodies I believe both methods would require the exact same response body, i.e. the response body would have to contain the current representation of the entire updated resource

可以只是 return 204 No Content200 OK 而没有响应 body。不要求他们在响应中包含完整的表示。

你可以选择支持这个(也许连同 Prefer: return=representation header,或者 Content-Location header),但如果没有这个 header 我会说当前的表示法是 returned 甚至不是约定俗成的。通用客户端 不应该 假定响应 body 是新的表示,除非使用这些 header。

所以,只需 return 一个 2xx 就可以了。

So what would be the proper response in this large collection scenario?

简短版本:您可能应该将成功的 PUT 视为成功的 POST。

the intended meaning of the payload can be summarized as: a representation of the status of, or results obtained from, the action

所以响应可以像

一样简单
200 OK
Content-Type: text/plain

It worked!

更长的答案:

While either method would require very different request bodies I believe both methods would require the exact same response body, i.e. the response body would have to contain the current representation of the entire updated resource

这是不对的 - 如果您查看 RFC 7231,您会看到对 PUT 的响应有这样的描述

a representation of the status of the action

返回资源的新表示是一种边缘情况,而不是默认情况(请参阅 Content-Location header 的规范)。

For a state-changing request like PUT (Section 4.3.4) or POST (Section 4.3.3), it implies that the server's response contains the new representation of that resource, thereby distinguishing it from representations that might only report about the action (e.g., "It worked!"). This allows authoring applications to update their local copies without the need for a subsequent GET request.


也就是说,我建议您检查一下您选择的方法令牌。 PUT 和 PATCH 都支持远程创作语义——要求服务器使其文档副本看起来像本地副本的消息。这就是为什么 PUT 规范对向响应添加验证器 header 字段有一堆限制。允许通用组件假设它们知道发生了什么,因为所有资源应该以相同的方式理解这些方法。

但在你的情况下,你不能真正说是远程创作 collection,因为客户端(和通用组件)没有 [=49= 的表示],而是仅表示 collection.

的页面

如果您要与统一界面保持一致,那么您可以

  • 允许远程创作页面,或
  • 放弃暗示远程创作的方法标记

It is okay to use POST 当您请求的语义与标准化含义不完全一致时

POST serves many useful purposes in HTTP, including the general purpose of “this action isn’t worth standardizing.”