在一个宁静的网址上编码分页信息的标准方法是什么?

时间:2009-05-30 12:57:40

标签: pagination rest friendly-url

我认为用几个例子可以更好地解释我的问题......

获取http://myservice/myresource/?name=xxx&country=xxxx&_page=3&_page_len=10&_order=name asc

也就是说,一方面我有条件(name = xxx& country = xxxx),另一方面我有影响查询的参数(_page = 3& _page_len = 10& _order = name asc)

现在,我虽然使用了一些特殊的前缀(在案例中为“_”)以避免条件和参数之间的冲突(如果我的资源有“订单”属性怎么办?)

是否有一些标准方法来处理这些情况?

-

我找到了这个例子(只是选择一个) http://www.peej.co.uk/articles/restfully-delicious.html

获取http://del.icio.us/api/peej/bookmarks/?tag=mytag&dt=2009-05-30&start=1&end=2

但在这种情况下,条件字段已经定义(没有开始或结束属性)

我正在寻找一些通用的解决方案......

- 编辑,一个更详细的例子来澄清

每个项目完全独立......让我们说我的资源是客户,而且(幸运的是)我的数据库中有数百万个。

所以网址可能是

http://myservice/customers/?country=argentina,last_operation=2009-01-01..2010-01-01

它应该给我去年购买任何东西的阿根廷客户

现在我想使用这个服务来构建一个浏览页面,或者用ajax填充一个组合,所以我的想法是添加一些metada来控制我应该得到什么信息

构建我要添加的浏览页面

http://...,_page=1,_page_len=10,_order=state,name

并使用ajax

填充autosuggest组合

http://...,_page=1,_page_len=100,_order=state,name,name=what_ever_type_the_user *

用最符合用户输入内容的100个客户填充组合...

我的问题是,是否有某种标准(书面或非书面)方式以完整的网址方式对这类内容进行编码......

4 个答案:

答案 0 :(得分:2)

没有标准或约定来定义这样做的方法,但使用下划线(一个或两个)来表示元信息并不是一个坏主意。这是用于在某些语言中按惯例指定成员变量的内容。

答案 1 :(得分:2)


注意: 我开始将此作为对my previous answer的评论。然后我打算将它添加为编辑,但我认为它只是作为一个单独的答案。这是一种完全不同的方法,它本身就是一个单独的答案,因为它是一种不同的方法。


我一直在考虑这个问题,我认为你真的有两种不同的资源需要处理:

  1. 资源页
  2. 收集到页面中的每个资源
  3. 我可能错过了一些东西(可能是......我犯了错误的解释)。由于页面本身就是一种资源,因此分页元信息实际上是资源的一个属性,因此将其放在URL中并不一定是错误的方法。如果考虑将来可以为页面缓存和/或将来称为资源的内容,则资源由分页属性和查询参数定义,因此它们都应位于URL中。为了继续我过于冗长的响应,页面资源将类似于:

    http://.../myresource/page-10/3?name=xxx&country=yyy&order=name&orderby=asc
    

    我认为这是你原来问题的核心。如果页面本身是一个资源,那么URI应该描述页面,所以类似page-10这样的方式是“10个页面的页面”,页面的下一部分是页码。查询部分包含过滤器。

    其他资源命名该页面包含的每个项目。如何识别物品应该由资源控制。我认为一个关键问题是结果资源是否独立存在。您如何表示资源根据此概念而有所不同。

    如果项目表示仅适用于页面上下文中,则可能适合将内容包含在内。如果您这样做,请单独识别它们,并确保您可以使用URI fragment syntaxan additional path element检索它们。似乎以下网址应该导致十个项目的第三页上的第五个项目:

    http://.../myresource/page-10/3?...#5
    http://.../myresource/page-10/3/5?...
    

    决定这两者之间的最大因素是单个项目与页面的强烈耦合程度。片段语法比路径元素IMHO绑定得多。

    现在,如果项目资源是独立的,并且页面只是查询的结果(我认为这可能就是这种情况),那么页面资源应该是每个项目资源的URL的有序列表。在这种情况下,项目资源应独立于页面资源。您可能希望使用基于项本身的标识属性的URI。所以你最终会得到类似的东西:

    http://.../myresource/item/42
    http://.../myresource/item/307E8599-AD9B-4B32-8612-F8EAF754DFDB
    

    关键决定因素是项目是否为独立资源。如果不是,那么它们是从页面URI派生的。如果它们是独立的,那么它们应该由它们自己的资源定义,并且应该作为链接包含在页面资源中。

答案 2 :(得分:2)

虽然没有标准,但在创建Web API时,Web API Design(由Apigee提供)是一本很好的建议书。我将其视为一种标准,并随时遵循其建议。

在“分页和部分回应”下,他们建议(第17页):

  

使用限制和偏移

     

我们建议限制和抵消。它在领先的数据库中更为常见,易于理解,并且易于开发人员使用。

/dogs?limit=25&offset=50

答案 3 :(得分:1)

我知道RESTful民众倾向于不喜欢使用HTTP标头,但实际上有人试图使用HTTP ranges来解决分页问题。几年前我写了一个ISAPI扩展,其中包括分页信息以及URI中的其他非属性信息,我从不真正喜欢它的感觉。我在想做类似的事情:

GET http://...?name=xxx&country=xxxx&_orderby=name&_order=asc HTTP/1.1
Range: pageditems=20-29
...

这会将结果集参数(例如_orderby_order)放入URI中,并将选择作为Range标头。我有一种感觉,大多数HTTP实现会搞砸了,特别是因为非字节范围的支持是RFC2616中的MAY。在与RTSP进行大量工作后,我开始更认真地考虑这个问题。 Range header in RTSP是扩展范围以处理时间和字节的一个很好的例子。

我想另一种处理方法是对页面上的每个项目单独请求作为单独的资源。如果您的代表允许这样做,那么您可能想要考虑它。中间缓存更有可能使用这种方法很好地工作。因此,您的资源将被定义为:

myresource/name=xxx;country=xxx/orderby=name;order=asc/20/
myresource/name=xxx;country=xxx/orderby=name;order=asc/21/
myresource/name=xxx;country=xxx/orderby=name;order=asc/22/
myresource/name=xxx;country=xxx/orderby=name;order=asc/23/
myresource/name=xxx;country=xxx/orderby=name;order=asc/24/

我不确定是否有人尝试过这样的事情。这将使URI可构造,这总是一个有用的属性恕我直言。这种方法的好处是可以缓存各个响应,服务器可以自由地优化处理收集项目的页面,而不是以最有效的方式。基本思想是让客户端在URI中指定查询以及它想要检索的项目的索引。无需将“page”的想法推入资源甚至使其可见。客户端可以迭代检索对象,直到它的页面已满或收到404。

当然有一个缺点...... HTTP服务器和基础设施必须支持pipelining,否则创建/破坏连接的成本可能会彻底扼杀这个想法。