2

上下文:假设我们要定期(每天、每小时或几分钟)检索给定用户的整个已加星标的存储库列表。

至少有两种方法可以做到这一点:

  1. 执行 GET 到https://api.github.com/users/evereq/starred并在 'Link' 响应标头中使用带有 rel='next' 的 Url 来获取下一页 Url(我们应该这样做直到我们没有“next”作为响应的页面,意味着我们到达了终点)。似乎这是推荐的方法(由 Github 提供)。

  2. 使用 GET 到https://api.github.com/users/evereq/starred?page=XXX迭代“页面”参数(从 1 到无限),直到您得到 0 个响应结果。你得到 0 个结果,你就完成了(不推荐,因为例如,Github 可以移动到“哈希”值而不是页码。Github 已经为一些 API 操作做到了。)。

现在,假设我们要确保使用条件请求(请参阅https://docs.github.com/en/rest/overview/resources-in-the-rest-api#conditional-requests)来保存我们的 API 使用限制(和交通,世界上的树木等)。

因此,我们将例如“If-None-Match”添加到我们的请求标头中,并检查响应状态是否为 304(未修改)。如果是这样,这意味着与我们上次的请求相比没有任何改变。这行得通。

然而,我们在上面 1) 和 2) 中遇到的问题与我们检测何时停止的方式有关,当您使用条件请求时不再起作用!

即使用方法 1),当您使用条件请求时,您根本不会获得链接响应标头。因此,您将需要执行一个比您已经拥有 ETag 的页面更大的页面的请求,并看到它返回 0 个结果,并且您知道您已经完成了。这样你基本上“浪费”了一个对 Github API 的请求(因为它错过了条件请求标头)。

与方法 2) 相同,您基本上在每个状态为 304 的请求中都有 0 个响应......所以再次,要知道您已完成,您需要至少发出一个额外的请求,该请求确实返回 0 个结果。

所以问题是:当我们使用 Github API 不发回链接响应标头(至少使用 ETag 导致状态 304 的查询)的事实进行条件请求时,我们如何知道何时停止分页?这是 Github API 实现中的错误还是我错过了什么?

我们不知道最大页码,所以要知道何时停止,我们应该再执行一个“浪费”请求并检查我们是否返回 0 个结果!

我也找不到如何在 Github 中查询已加星标的存储库的总数(所以我可以计算我应该在建议中迭代多少页),就像响应不包括“X-Total-Count”之类的东西所以我知道什么时候停止使用简单的数学计算页数。

任何想法如何保存一个(“结束”)请求并仍然使用条件请求?

如果你每天做一个请求,接受这样的浪费是可以的,但是如果你每分钟做一个请求呢?您将快速使用所有 API 使用限制!

更新

好吧,经过几次测试,我现在看到遵循“规则”(但是在文档中的任何地方都找不到它,所以请注意它的规则或只是假设):如果用户为新内容加注星标,则每个请求页面的结果都包含与以前相比,ETag 值不同,并且不再有状态 304!这意味着只请求首页并检查状态就足够了。如果它是 304(未修改),我们不需要检查下一页,即我们完成了,因为任何页面都没有更改。这是正确的方法还是只是巧合?

4

1 回答 1

1

当内容发生变化时,我们确实在Link响应头中返回分页关系1。由于我们不支持since该调用的参数,您需要按最近的结果进行排序,并为最后一个已知 ID 或时间戳(基于您的排序标准)维护客户端游标,并在显示时停止分页在您的分页结果中。有条件的请求只会让您知道第 1 页是否已更改。

我们还没有确定在我们的列表方法中返回计数的方法,但是一个非常低技术的解决方案是将页面大小设置为 1,获取rel=lastLink 关系并检查其page参数值。

希望有帮助。

于 2013-08-28T14:48:30.440 回答