RESTful API 设计中的分页问题
Posted
技术标签:
【中文标题】RESTful API 设计中的分页问题【英文标题】:Pagination issue in RESTful API design 【发布时间】:2015-03-23 10:08:50 【问题描述】:我正在为我正在开发的移动应用程序设计一个 RESTful API。我的问题是包含许多项目的大型集合。我知道一个好的做法是对集合中的大量结果进行分页。
我已阅读 Facebook Graph API 文档 (https://developers.facebook.com/docs/graph-api/using-graph-api/v2.2)、Twitter 游标文档 (https://dev.twitter.com/overview/api/cursoring)、GitHub API 文档 (https://developer.github.com/v3/) 和这篇文章 (API pagination best practices)。
在我的 API 中考虑一个示例集合 /resources
,它包含 100 个名为 resource1
到 resource100
并按降序排序的项目。这是您在 GET 请求 (GET http://api.path.com/resources?limit=5
) 时将得到的响应:
"_links":
"self": "href": "/resources?limit=5&page=1" ,
"last": "href": "/resources?limit=5&page=7" ,
"next": "href": "/resources?limit=5&page=2"
,
"_embedded":
"records": [
resource 100 ,
resource 99 ,
resource 98 ,
resource 97 ,
resource 96
]
现在我的问题是这样的场景:
1- 我得到/resources
上面的内容。
2- 之后,将某些内容添加到资源集合中(例如,另一台设备为此帐户添加了新资源)。所以现在我有 101 个资源。
3- 我 GET /resources?limit=5&page=2
最初的响应表明将包含我的结果的下一页。响应是这样的:
"_links":
"self": "href": "/history?page=2&limit=5" ,
"last": "href": "/history?page=7&limit=5" ,
"next": "href": "/history?page=3&limit=5"
,
"_embedded":
"records": [
resource 96 ,
resource 95 ,
resource 94 ,
resource 93 ,
resource 92
]
如您所见,resource 96
在两个页面中都重复出现(或者如果在第 2 步中删除资源,可能会出现类似问题,在这种情况下,一个资源将丢失)。
由于我想在一个移动应用程序和一个列表中使用它,我必须将每个 API 调用的资源附加到它之前的那个,这样我才能得到一个完整的列表。但这令人不安。如果您有任何建议,请告诉我。提前谢谢你。
P.S:我考虑过像查询字符串这样的时间戳,而不是基于光标的分页,但这会给我在其他地方带来问题。 (如果您需要更多相关信息,请告诉我。)
【问题讨论】:
为什么不同时使用基于光标的分页和时间戳? 【参考方案1】:我们刚刚通过 REST API 为移动应用实现了类似的功能。移动应用传递了一个额外的查询参数,该参数表示页面中的元素应该被“冻结”的时间戳。
所以你的第一个请求看起来像GET /resources?limit=5&page=1&from=2015-01-25T05:10:31.000Z
,然后第二个页面请求(一段时间后)会增加页面计数但保持相同的时间戳:GET /resources?limit=5&page=2&from=2015-01-25T05:10:31.000Z
如果移动应用想要区分“软”页面(保留页面 1 请求的时间戳)和“硬刷新”页面(将时间戳重置为当前时间),这也会给予移动应用控制权。
【讨论】:
非常感谢您的回复。是的,我正在考虑这种方法,但正如我在 P.S 中所说的那样,这可能会给我带来更多问题。无论如何,如果我最终使用此解决方案,我会将您的答案标记为已接受。再次感谢。 好吧,我最终做了基于光标的和之前/之后的时间戳。将此添加到您的答案中,我会接受。非常感谢:) 除了我不明白为什么你会在每个请求中同时使用之前和之后的时间戳,你也没有解释为什么只使用一个时间戳会给你带来问题。 @JonathanW 那么你什么时候更新并保存'from'值呢? @pe60t0 对于我参与的移动应用程序,应用程序本身会在发出下拉刷新时执行此操作。当向列表底部进行无限滚动时,它会发送相同的时间戳。有意义吗?【参考方案2】:为什么不只维护一组可见资源?
然后,当您处理每个响应时,您可以检查资源是否已被呈现。
【讨论】:
这只会阻止某些事情在视图中重复,但在较低级别上,我正在浪费时间执行 API 调用,而这些调用并没有让我得到我想要的。 (如果添加了 20 个资源,想象我的第 2 步)以上是关于RESTful API 设计中的分页问题的主要内容,如果未能解决你的问题,请参考以下文章