我有兴趣向 JSON 文档集合公开一个直接的 REST 接口(想想CouchDB http://couchdb.apache.org/ or 坚持不懈 http://persvr.org/)。我遇到的问题是如何处理GET
如果集合很大,则对集合根进行操作。
举个例子,假设我正在公开 StackOverflow 的Questions
表中的每一行都作为一个文档公开(不一定存在这样的表,只是一个相当大的“文档”集合的具体示例)。该系列将在以下网址提供:/db/questions
使用通常的 CRUD apiGET /db/questions/XXX
, PUT /db/questions/XXX
, POST /db/questions
正在播放。获取整个集合的标准方法是GET /db/questions
但是,如果将每一行天真地转储为 JSON 对象,您将获得相当大的下载量,并且服务器会承担大量工作。
解决方案当然是分页。 Dojo 已经解决了这个问题JsonRestStore http://docs.dojocampus.org/dojox/data/JsonRestStore#id7通过巧妙的 RFC2616 兼容扩展使用Range
带有自定义范围单位的标题items
。结果是206 Partial Content
仅返回请求的范围。与查询参数相比,这种方法的优点是它将查询字符串留给...查询(例如GET /db/questions/?score>200
或者类似的东西,是的,会被编码%3E
).
这种方法完全涵盖了我想要的行为。问题是RFC 2616 https://www.rfc-editor.org/rfc/rfc2616指定在 206 响应中(强调我的):
The request必须包含 Range 标头字段(第 14.35 条 https://www.rfc-editor.org/rfc/rfc2616#section-14.35)
指示所需的范围,并且可以包含 If-Range
标头字段(第 14.27 条 https://www.rfc-editor.org/rfc/rfc2616#section-14.27) 使请求成为有条件的。
这在标头的标准用法的上下文中是有意义的,但这是一个问题,因为我希望 206 响应成为默认值来处理天真的客户端/随机的人探索。
我已经详细阅读了 RFC 寻找解决方案,但对我的解决方案不满意,并且对 SO 对这个问题的看法感兴趣。
我曾经有过的想法:
-
Return
200
with a Content-Range
header!- 我不认为这是错误的,但我更希望有一个更明显的指示,表明响应只是部分内容。
-
Return
400 Range Required
- 所需标头没有特殊的 400 响应代码,因此必须使用默认错误并手动读取。这也使得通过网络浏览器(或其他一些客户端,如 Resty)进行探索变得更加困难。
-
使用查询参数- 标准方法,但我希望允许查询 la Persevere,这会切入查询名称空间。
-
刚回来
206
!- 我认为大多数客户不会惊慌失措,但我不想违背 RFC 中的“必须”
-
扩展规格!返回
266 Partial Content
- 行为与 206 完全相同,但响应不得包含Range
标头。我认为 266 足够高,我不应该遇到冲突问题,这对我来说很有意义,但我不清楚这是否被视为禁忌。
我认为这是一个相当普遍的问题,我希望看到这以某种事实上的方式完成,这样我或其他人就不会重新发明轮子。
当集合很大时,通过 HTTP 公开完整集合的最佳方法是什么?