修补集合时的响应主体

如何解决修补集合时的响应主体

在我的REST API中,我有一个很大的集合;它包含数百万个项目。该集合的路径为/mycollection

由于此集合太大,因此GET整个集合不是一个好习惯,因此API支持分页分页将是获取收藏的主要方式

GET /mycollection?page=1&page-size=100 HTTP/1.1

说原始集合包含1,000,000个项目,而我想更新5,000,删除3,000和添加2,000个项目。我可以编写自己的API以支持通过PUT方法PATCH方法更新集合。尽管这两种方法都需要非常不同的请求主体,但我相信这两种方法都需要完全相同的响应主体,即,响应主体必须包含整个更新资源的当前表示形式,即集合中的所有999,000项。

正如我之前提到的GET仅对整个集合进行评估是不现实的;这个太大了。由于相同的原因,我不希望PUTPATCH归还整个收藏。将查询参数添加PUTPATCH请求中将不会起作用,因为PUTPATCH都不是安全的方法

那么在这种大收集情况下,正确的响应是什么?

我可以回应

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

202 Accepted响应代码不正确,因为更新将同步完成。 Location标头也不太正确。我也许可以使用Links标头,但感觉仍然不合适。

再次,我问在这种大收集情况下正确的反应是什么?

解决方法

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

虽然两种方法都需要非常不同的请求主体,但我相信两种方法都需要完全相同的响应主体,即,响应主体必须包含整个更新资源的当前表示形式

任何人都只能返回204 No Content200 OK而没有响应正文。不需要在响应中包含完整的表示形式。

您可以选择支持此功能(可能与Prefer: return=representation标头或Content-Location标头一起使用),但是如果没有此标头,我会说返回当前表示形式甚至不是约定。通用客户端不应假定响应主体是新的表示形式,除非使用了这些标头。

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

,

那么在这种大收集情况下,正确的响应是什么?

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

有效载荷的预期含义可以概括为: 动作状态或结果的代表

所以响应可能很简单

200 OK
Content-Type: text/plain

It worked!

更长的答案:

虽然两种方法都需要非常不同的请求主体,但我相信两种方法都需要完全相同的响应主体,即,响应主体必须包含整个更新资源的当前表示形式

这是不对的-如果您查看RFC 7231,将会看到对PUT的回复中包含以下说明

动作状态的表示

返回资源的新表示形式是一种极端情况,而不是默认情况(请参见Content-Location标头的规范)。

对于诸如PUT(第4.3.4节)或POST(第4.3.3节)之类的状态更改请求,这意味着服务器的响应包含该资源的新表示形式,从而将其与可能仅报告有关以下内容的表示形式区分开来:动作(例如“成功了!”)。这样一来,创作应用程序即可更新其本地副本,而无需后续的GET请求。


也就是说,我建议您回顾一下方法标记的选择。 PUT和PATCH均支持远程创作语义-要求服务器使其文档副本像本地副本一样的消息。这就是例如PUT规范在将验证器标头字段添加到响应中有很多约束的原因。通用组件可以假定它们知道发生了什么,因为所有 资源应该以相同的方式理解这些方法。

但是在您的情况下,您不能真的说您是远程创作该集合,因为客户端(和通用组件)没有该集合的表示,而是只有该页面的表示集合。

如果您要与统一界面保持一致,则可以选择

  • 允许页面的远程创作,或者
  • 放弃暗示远程创作的方法令牌

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

POST在HTTP中有许多有用的用途,包括“此操作不值得标准化”的一般用途。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?