Http Rest集合中的分页

Http Rest集合中的分页,http,rest,http-headers,pagination,Http,Rest,Http Headers,Pagination,我感兴趣的是将直接REST接口公开给JSON文档集合(想想或者)。我遇到的问题是,如果集合很大,如何处理集合根上的GET操作 例如,假设我公开StackOverflow的问题表,其中每一行都作为文档公开(不一定有这样的表,只是一个大型“文档”集合的具体示例)。该集合将在/db/questions上提供,使用通常的CRUD apiGET/db/questions/XXX,PUT/db/questions/XXX,POST/db/questions。获取整个集合的标准方法是get/db/questi

我感兴趣的是将直接REST接口公开给JSON文档集合(想想或者)。我遇到的问题是,如果集合很大,如何处理集合根上的
GET
操作

例如,假设我公开StackOverflow的
问题
表,其中每一行都作为文档公开(不一定有这样的表,只是一个大型“文档”集合的具体示例)。该集合将在
/db/questions
上提供,使用通常的CRUD api
GET/db/questions/XXX
PUT/db/questions/XXX
POST/db/questions
。获取整个集合的标准方法是
get/db/questions
,但是如果这天真地将每一行作为JSON对象转储,那么您将获得相当大的下载量,并且服务器部分需要做大量工作

当然,解决方案是分页。Dojo通过一个巧妙的RFC2616兼容扩展解决了这个问题,该扩展将
范围
标题与自定义范围单位
一起使用。结果是
206部分内容
,只返回请求的范围。与查询参数相比,这种方法的优点是它为…查询保留查询字符串(例如,
GET/db/questions/?score>200
或类似的,是的,将被编码为
%3E

这种方法完全涵盖了我想要的行为。问题在于,在206响应上(强调矿山):

请求必须包含范围标头字段() 指示所需范围,可能包括If范围 标头字段()使请求有条件

这在头的标准用法的上下文中是有意义的,但这是一个问题,因为我希望206响应是处理天真客户端/随机用户的默认响应

我已经详细检查了RFC,寻找解决方案,但对我的解决方案不满意,我对SO的问题感兴趣

我的想法是:

  • 使用
    内容范围
    标题返回
    200
    我不认为这是错误的,但我更希望有一个更明显的指标,表明回应只是部分内容
  • Return
    400 Range Required
    -对于所需的标题,没有特殊的400响应代码,因此必须使用默认错误并手动读取。这也使得通过web浏览器(或其他类似Resty的客户端)进行探索变得更加困难
  • 使用一个查询参数——这是标准的方法,但我希望允许查询持久化,这将切入查询名称空间
  • 只需返回
    206
    !-我想大多数客户都不会惊慌失措,但我不想违背RFC的规定
  • 扩展规格!Return
    266部分内容
    -行为与206完全相同,但响应的请求不得包含
    范围
    标题。我认为266足够高,我不应该遇到碰撞问题,这对我来说是有意义的,但我不清楚这是否被视为禁忌
我认为这是一个相当普遍的问题,我希望看到它以一种事实上的方式完成,这样我或其他人就不会重新发明轮子了


当集合很大时,通过HTTP公开完整集合的最佳方式是什么?

我的直觉是HTTP范围扩展不是为您的用例设计的,因此您不应该尝试。部分响应意味着
206
,只有在客户要求时才能发送
206


您可能想考虑一种不同的方法,例如Atom中的一种用法(其中设计的表示可能是部分的,并且返回状态为代码< 200)/代码>,以及潜在的分页链接。你可以考虑使用一个模型,比如Atom提要协议,因为它有一个明智的HTTP集合模型,以及如何操作它们(疯狂的意思是WebDAV)。p> 还有一个定义集合模型和REST操作的方法,另外,您还可以使用它在大型集合中翻页

从Atom XML切换到JSON内容不应影响想法。

编辑:

仔细考虑之后,我倾向于同意范围标头不适合分页。逻辑是,范围标头用于服务器的响应,而不是应用程序。如果您提供了100兆字节的结果,但服务器(或客户端)一次只能处理1兆字节,那么,这就是范围标头的作用

我还认为资源的子集是它自己的资源(类似于关系代数),因此它应该在URL中表示

所以基本上,我放弃了关于使用标题的原始答案(如下)


我想您已经回答了自己的问题,或多或少-返回200或206,并带有内容范围,还可以选择使用查询参数。我会嗅探用户代理和内容类型,并根据它们检查查询参数。否则,需要范围标头

你的目标基本上是相互冲突的——让人们使用他们的浏览器来浏览(这不容易允许自定义标题),或者强迫人们使用可以设置标题的特殊客户端(这不允许他们浏览)

您可以根据请求为他们提供特殊的客户端——如果它看起来像一个普通的浏览器,则发送一个小型ajax应用程序来呈现页面并设置必要的标题

当然,关于URL是否应该包含这类事情所需的所有状态,也存在争论。某些人认为使用头指定范围是“非restful”的

另一方面,如果服务器可以响应“Can Specify:Header1,header2”标题,web浏览器将显示一个UI,以便用户可以在需要时填写值,那就太好了
Link: <>; rel="http://paged.collection.example/relation/paged"
Link: <>; rel="http://paged.collection.example/relation/paged"
...
GET /db/questions HTTP/1.1
Host: paged.collection.example
Accept: application/json;PagingSpec=1.0;page=1