这是这个问题的一个更通用的重新表述(消除了Rails特定的部分)

我不确定如何在RESTful web应用程序中实现资源分页。 假设我有一个叫做产品的资源,你认为以下哪一个是最好的方法,为什么:

1. 只使用查询字符串

如。http://application/products?page=2&sort_by=date&sort_how=asc 这里的问题是,我不能使用全页缓存,而且URL不是很干净,容易记住。

2. 使用页面作为资源和查询字符串进行排序

如。http://application/products/page/2?sort_by=date&sort_how=asc 在这种情况下,我们看到的问题是http://application/products/pages/1不是唯一的资源,因为使用sort_by=price可以产生完全不同的结果,我仍然不能使用页面缓存。

3.使用页面作为资源,并使用URL段进行排序

如。http://application/products/by-date/page/2 我个人认为使用这种方法没有问题,但有人警告我这不是一个好的方法(他没有给出理由,所以如果你知道为什么不推荐,请告诉我)

任何建议,意见,批评都是非常欢迎的。谢谢。


当前回答

我在我的项目中使用以下url:

http://application/products?page=2&sort=+field1-field2

意思是"给我第二页按field1升序,然后按field2降序"或者如果我需要更大的灵活性,我会使用:

http://application/products?skip=20&limit=20&sort=+field1-field2

其他回答

我认为版本3的问题更多的是一个“观点”问题——你把页面看作资源还是页面上的产品。

如果将页面视为资源,这是一个完美的解决方案,因为对第2页的查询总是会返回第2页。

但是,如果您将页面上的产品视为资源,那么第2页上的产品可能会发生变化(旧产品被删除或其他),在这种情况下,URI并不总是如此 返回相同的资源。

例如,客户存储了一个到产品列表X页的链接,下次该链接被打开时,问题产品可能不再在X页。

我目前正在我的ASP中使用类似于此的方案。NET MVC应用程序:

例如,http://application/products/by-date/page/2

具体来说是:http://application/products/Date/Ascending/3

但是,我并不喜欢以这种方式在路由中包括分页和排序信息。

项目列表(在本例中为产品)是可变的。也就是说,下次有人返回包含分页和排序参数的url时,他们得到的结果可能已经改变了。因此,将http://application/products/Date/Ascending/3作为指向一组确定的、不变的产品的唯一url的想法就消失了。

我更喜欢使用查询参数offset和limit。

偏移量:用于集合中项目的索引。

限制:为项目的数量。

客户端可以简单地继续更新偏移量,如下所示

offset = offset + limit

下一页。

路径被认为是资源标识符。页面不是资源,而是资源集合的子集。由于分页通常是一个GET请求,因此查询参数最适合用于分页,而不是用于标头。

参考:https://metamug.com/article/rest-api-developers-dilemma.html # Requesting-the-next-page

为了寻找最佳实践,我看到了这个网站:

http://www.restapitutorial.com

在参考资料页中有一个链接,可以下载一个.pdf文件,其中包含作者建议的完整REST最佳实践。其中有一节是关于分页的。

作者建议同时支持使用Range头和使用查询字符串参数。

请求

HTTP报头示例:

Range: items=0-24

查询字符串参数示例:

GET http://api.example.com/resources?offset=0&limit=25

其中offset是开始项数,limit是返回的最大项数。

响应

响应应该包括一个Content-Range报头,指示有多少项正在返回,以及总共有多少项尚待检索

HTTP报头示例:

Content-Range: items 0-24/66

Content-Range: items 40-65/*

在.pdf文件中,还有一些针对更具体情况的其他建议。

我在我的项目中使用以下url:

http://application/products?page=2&sort=+field1-field2

意思是"给我第二页按field1升序,然后按field2降序"或者如果我需要更大的灵活性,我会使用:

http://application/products?skip=20&limit=20&sort=+field1-field2