我有兴趣公开将多个JSON文档集合暴露为直接的REST接口(类似于CouchDB或Persevere)。我遇到的问题是如何处理集合根节点的GET
操作,如果集合很大会怎么样。
举例来说,假设我正在公开StackOverflow的Questions
表格,其中每一行都作为一个文档公开(并不一定有这样的表格,只是一个具体的“文档”数量可观的集合的示例)。该集合将在/db/questions
下提供,并使用通常的CRUD api,例如GET /db/questions/XXX
,PUT /db/questions/XXX
以及POST /db/questions
。获取整个集合的标准方法是GET /db/questions
,但是如果轻率地将每一行作为JSON对象转储,则会得到相当大的下载量并且服务器也需要进行大量工作。
Range
头的巧妙RFC2616兼容扩展,在其JsonRestStore中解决了此问题。结果是一个返回仅请求的范围的206 Partial Content
。这种方法优于查询参数的优点在于它将查询字符串留给...查询(例如GET /db/questions/?score>200
或类似的内容,是编码为%3E
的)。这种方法完全覆盖了我想要的行为。问题在于RFC 2616规定在206响应(重点是我的)时:
在标头的标准用法上,这是有道理的,但是这是一个问题,因为我希望206响应成为处理天真客户端/随机探索者的默认值。请求必须包含一个Range头字段(第14.35节),指示所需范围,并且可以包含一个If-Range头字段(第14.27节)使请求有条件。
我已经详细研究了RFC,寻找解决方案,但我的解决方案并不满意,我很想知道SO对这个问题的看法。
我有过的想法:
- 使用
Content-Range
头返回200
! - 我认为这并没有错,但我更希望有一个更明显的指示符表明响应仅为部分内容。 - 返回
400 Range Required
- 没有特殊的400响应代码用于必需的标头,因此必须使用默认错误并手动读取。这也使得通过Web浏览器(或像Resty这样的其他客户端)进行探索更加困难。 - 使用查询参数 - 标准方法,但我希望允许类似于Persevere的查询,这会占用查询命名空间。
- 只需返回
206
! - 我认为大多数客户端不会感到恐慌,但我不想违反RFC中的MUST规定 - 扩展规范!返回
266 Partial Content
- 与206完全相同,但是响应请求不能包含Range
头。我认为266足够高,不会遇到冲突问题,并且对我来说很有意义,但我不清楚这是否被认为是禁忌。
我认为这是一个相当普遍的问题,我希望以某种事实上的方式解决这个问题,这样我或其他人就不必重新发明轮子。
在集合很大的情况下,公开完整集合的最佳方法是什么?
Range = "Range" ":" ranges-specifier
,其中http://tools.ietf.org/html/rfc2616#section-14.35.1中的后者仅被描述为“byte-ranges-specifier”,它必须以“bytes-unit”开头,该字符串被定义为“bytes”。 - Brett ZamirContent-Range
头部适用于请求体(可用于上传大文件等请求时,或下载响应时)。Range
头部用于请求特定范围。当请求中包含Range
头部时,应该使用206
响应。如果没有,则响应仍可以包括Content-Range
头部,但响应代码应为200
。这个头部实际上似乎非常适合分页。 - Stijn de Witt