我有兴趣将直接REST接口暴露给JSON文档集合(想想CouchDB或Persevere).我遇到的问题是GET如果集合很大,如何处理集合根上的操作.
作为一个例子假装我暴露StackOverflow的Questions表,其中每一行都作为文档公开(不一定是这样的表,只是一个相当大的'文档'集合的具体例子).收集将在可提供/db/questions与通常的CRUD API GET /db/questions/XXX,PUT /db/questions/XXX,POST /db/questions是在玩.获取整个集合的标准方法是,GET /db/questions但如果天真地将每一行转储为JSON对象,那么您将获得相当大的下载和服务器上的大量工作.
解决方案当然是分页.Dojo 通过一个巧妙的RFC2616兼容扩展使用带有自定义范围单元的标头,在其JsonRestStore中解决了这个问题.结果是只返回请求的范围.这种方法优于查询参数的优点是它为查询留下了查询字符串(例如,或某些,以及是的,它被编码).Rangeitems206 Partial ContentGET /db/questions/?score>200%3E
这种方法完全涵盖了我想要的行为.问题是RFC 2616指定206响应(强调我的):
该请求必须具有包含Range头部字段(部分14.35),指示在期望的范围,并且可以具有包括一个If-Range头字段(部分14.27),以使所述请求为条件.
这在标题使用标题的上下文中是有意义的,但是是一个问题因为我希望206响应是默认处理天真客户端/随机人员探索.
我已经仔细研究了RFC,寻找解决方案,但对我的解决方案一直不满意,并对SO对这个问题的看法感兴趣.
我有过的想法:
200了Content-Range头! - 我不认为这是错的,但我更喜欢一个更明显的指标,即响应只是部分内容.400 Range Required - 所需标头没有特殊的400响应代码,因此必须手动使用和读取默认错误.这也使得通过Web浏览器(或像Resty这样的其他客户端)进行探索变得更加困难.206吧! - 我认为大多数客户都不会惊慌失措,但我宁愿不反对RFC中的MUST266 Partial Content - 行为与206完全相同,但是响应于不得包含Range …我编写了一个支持标准CRUD操作的RESTful Web服务,它可以返回一组符合特定条件的对象(SEARCH动词),但是我想添加一个更高阶的COUNT动词,因此客户端可以计算匹配搜索条件的资源,而不必获取所有这些资源.
我遇到的一些选择:
忽略HTTP规范并在HEAD请求的响应主体中返回对象计数.
复制SEARCH动词的逻辑,但是发出HEAD请求而不是GET请求.然后,服务器将对响应头中的对象计数进行编码.
定义一个新的HTTP方法COUNT,它返回响应主体中的对象计数.
我更喜欢第一种方法的API,但我必须选择该选项,因为它不符合要求.第二种方法似乎在语义上最正确,但API不是很方便:客户端必须处理响应头,大多数时候他们希望能够做一些简单的事情response.count.所以我倾向于第三种方法,但我担心定义新的HTTP方法可能会遇到的问题.
你会怎么做?
核心问题是关于HTTP标头的使用,包括Range,If-Range,Accept-Ranges和用户定义的范围说明符.
这是一个制作示例,以帮助说明我的问题.假设我有一个Web 2.0样式的应用程序,它显示某种人类可读的文档.这些文档在编辑上分为几页(类似于您在新闻网站上看到的文章).对于此示例,假设:
/document/shell/http-range-question)知道有关文档的元信息,包括页面数./document/content/http-range-question?page=1/document/content/http-range-question?page=2/document/content/http-range-question?page=3/document/content/http-range-question现在回答这个问题.我可以使用HTTP Range标头而不是URL的一部分(例如查询字符串参数)吗?在GET /document/content/http-range-question请求上可能是这样的:
Range: page=1
看起来规范只定义字节范围是允许的,所以即使我让我的ajax调用与我的浏览器和服务器代码一起工作,中间的任何东西都可能破坏合同(例如缓存代理服务器).
Range: bytes=0-499
自定义范围说明符的任何意见或现实世界的例子?
更新:我确实找到了一个关于Range标头(在Rest集合中分页)的类似问题,他们提到Dojo的JsonRestStore使用自定义Range标头值.
Range: items=0-24
我搜索了很多,但我找不到这个问题的好答案.作为一名HATEOAS爱好者,我认为这个标题非常适合:
    Range: item=1-20/100
在HTTP规范中,我不明白一些"矛盾":范围单位可以接受"其他范围单位"......
  range-unit       = bytes-unit | other-range-unit
  bytes-unit       = "bytes"
  other-range-unit = token
......但规范后来明确了:
HTTP/1.1定义的唯一范围单位是"字节".HTTP/1.1实现可以忽略使用其他单元指定的范围.
最后,该规范以此声明结束:
HTTP/1.1旨在允许实现不依赖于范围知识的应用程序.
注意:我不关心"可浏览性".