API分页最佳实践

我喜欢一些帮助处理一个奇怪的边缘情况与我正在建设的分页API。

像许多API一样,这个分页结果很大。 如果你查询/ foos,你会得到100个结果(即foo#1-100)和一个到/ foos?page = 2的链接,它应该返回foo#101-200。

不幸的是,如果在API消费者进行下一个查询之前从数据集中删除foo#10,那么/ foos?page = 2将偏移100并返回foos#102-201。

对于试图拉动所有foos的API消费者来说,这是一个问题 - 他们不会收到foo#101。

处理这个问题的最佳做法是什么? 我们希望尽可能轻量化(即避免处理API请求的会话)。 来自其他API的示例将不胜感激!


我不完全确定你的数据是如何处理的,所以这可能会或可能不会起作用,但是你是否考虑过使用时间戳字段进行分页?

当你查询/ foos时,你会得到100个结果。 然后你的API应该返回类似的东西(假设JSON,但是如果它需要XML,可以遵循相同的原则):

{
    "data" : [
        {  data item 1 with all relevant fields    },
        {  data item 2   },
        ...
        {  data item 100 }
    ],
    "paging":  {
        "previous":  "http://api.example.com/foo?since=TIMESTAMP1" 
        "next":  "http://api.example.com/foo?since=TIMESTAMP2"
    }

}

请注意,只有使用一个时间戳会依赖于结果中的隐式“限制”。 您可能需要添加明确的限制,或者使用until属性。

时间戳可以使用列表中的最后一个数据项来动态确定。 这似乎或多或少是Facebook如何在Graph API中进行分页(向下滚动到底部以按照上面给出的格式查看分页链接)。

一个问题可能是如果你添加一个数据项,但是根据你的描述,它听起来像将被添加到最后(如果没有,让我知道,我会看看如果我可以改善这一点)。


你有几个问题。

首先,你有你引用的例子。

如果插入行,您也会遇到类似的问题,但在这种情况下,用户会得到重复的数据(可以说比丢失数据更容易管理,但仍然是一个问题)。

如果你没有对原始数据集进行快照,那么这只是一个事实。

你可以让用户做一个明确的快照:

POST /createquery
filter.firstName=Bob&filter.lastName=Eubanks

结果如下:

HTTP/1.1 301 Here's your query
Location: http://www.example.org/query/12345

然后你可以整天翻页,因为它现在是静态的。 这可以是相当轻的重量,因为您可以捕获实际的文档键而不是整行。

如果用例仅仅是您的用户需要(并且需要)所有数据,那么您可以简单地将其提供给他们:

GET /query/12345?all=true

并发送整个套件。


如果你已经分页,你也可以通过一些关键字对数据进行排序。 为什么不让API客户端在URL中包含先前返回的集合的最后一个元素的关键字,并向SQL查询中添加WHERE子句(或者如果您不使用SQL,则是等价的),以便它仅返回那些用于哪个键大于这个值?

链接地址: http://www.djcxy.com/p/45657.html

上一篇: API pagination best practices

下一篇: Best practice to return errors in ASP.NET Web API