我感兴趣的是将一个直接的 REST 接口公开给 JSON 文档集合(想想 CouchDB或 坚持下去)。我遇到的问题是,如果集合很大,如何处理集合根目录上的 GET
操作。
作为一个例子,假设我正在公开 StackOverflow 的 Questions
表,其中每一行都被公开为一个文档(并不一定有这样一个表,只是一个大量“文档”集合的具体例子)。收集将提供在 /db/questions
与通常的 CRUD api GET /db/questions/XXX
,PUT /db/questions/XXX
,POST /db/questions
是在发挥。获取整个集合的标准方法是使用 GET /db/questions
,但是如果将每一行作为 JSON 对象转储,那么您将获得相当大的下载量,并且服务器部分将进行大量工作。
当然,解决方案是分页。Dojo 已经在其 JsonRestStore中解决了这个问题,方法是通过一个聪明的兼容 RFC2616的扩展,即使用带有定制范围单元 items
的 Range
报头。结果是只返回请求范围的 206 Partial Content
。与查询参数相比,这种方法的优势在于它将查询字符串留给... 查询(例如,GET /db/questions/?score>200
或某些类似的查询,是的,这将被编码为 %3E
)。
这种方法完全涵盖了我想要的行为。问题是,RFC 2616在206响应(重点是我的)中指明:
请求必须包含一个 Range 头字段(第14.35节) 指示所需的范围,并且可能包括一个 If-Range 头字段(第14.27节)使请求有条件。
这在标题的标准用法的上下文中是有意义的,但是这是一个问题,因为我希望206响应默认用于处理天真的客户机/随机浏览者。
我仔细研究了 RFC,希望找到一个解决方案,但是对我的解决方案不满意,我对 SO 对这个问题的看法很感兴趣。
我有一些想法:
Content-Range
头的 200
!我不认为这是错误的,但是我更希望有一个更明显的指示,即响应只是部分内容。400 Range Required
-对于所需的头没有特殊的400响应代码,因此必须使用默认错误并手动读取。这也使得通过 Web 浏览器(或者其他客户端,比如 Resty)进行探索变得更加困难。206
!我认为大多数客户不会抓狂,但是我不想违反 RFC 中的必须条款266 Partial Content
-行为与206完全相同,但是响应的请求必须不包含 Range
头。我认为266已经足够高了,我不应该遇到碰撞问题,这对我来说是有意义的,但我不清楚这是否被认为是禁忌。我认为这是一个相当普遍的问题,我希望看到这个问题以一种事实上的方式解决,这样我或其他人就不会有重造轮子。
当集合很大时,通过 HTTP 公开完整集合的最佳方式是什么?