【发布时间】:2013-08-31 14:49:17
【问题描述】:
上下文:假设我们要定期检索给定用户的整个已加星标的存储库列表(每天、每小时或几分钟)。
至少有两种方法可以做到这一点:
-
执行 GET 到 https://api.github.com/users/evereq/starred 并在 'Link' 响应标头中使用带有 rel='next' 的 Url 来获取下一页 Url(我们应该这样做,直到我们没有得到“下一页”响应,这意味着我们到达结尾)。似乎这是推荐的方法(由 Github 提供)。
-
使用 GET 迭代“页面”参数(从 1 到无限)到 https://api.github.com/users/evereq/starred?page=XXX,直到您得到 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(未修改),我们不需要检查下一页,即我们完成了,因为任何页面都没有更改。这是正确的做法还是巧合?
【问题讨论】:
标签: api caching github paging etag