12

我有一个关于 API 调用缓存的一般性问题,在这种情况下调用 Github API。

假设我的应用中有一个页面,其中显示了 repo 的文件名和 README 的内容。这意味着我必须进行一些 API 调用才能检索它。

现在,假设我想在两者之间添加类似 memcached 的东西,所以我不会一遍又一遍地进行这些调用,如果我不需要的话。

你通常会如何处理这件事?如果我不在 Github 上启用 webhook,我无法知道缓存是否应该过期。我总是可以进行一次调用来获取 HEAD 的当前 sha,如果它没有更改,请改用缓存。但这是在回购级别,而不是在文件级别。

我可以想象我可以用 object-sha 做类似的事情,但如果我需要调用 API 来获取这些,它就违背了缓存的目的。

你会怎么做?我知道像 prose.io 这样的服务现在没有缓存,但如果应该的话,方法是什么?

谢谢

4

1 回答 1

18

仅使用 HTTP 缓存是否足以满足您的用例?HTTP 缓存的目的不仅仅是提供一种在您已经有新响应时不发出请求的方法,而是 - 它还使您能够快速验证缓存中已有的响应是否有效(无需服务器发送完整的如果它是新鲜的,请再次回复)。

查看 GitHub API 响应,我可以看到 GitHub 正确设置了相关的 HTTP 标头(ETag、Last-modified、Cache-control)。

因此,您只需执行 GET,例如:

GET https://api.github.com/users/izuzak/repos

这会返回:

200 OK
...
ETag:"df739f00c5053d12ef3c625ad6b0fd08"
Last-Modified:Thu, 14 Feb 2013 22:31:14 GMT
...

下一次 - 您对同一资源执行 GET,但还提供相关的 HTTP 缓存标头,以便它实际上是一个条件 GET:

GET https://api.github.com/users/izuzak/repos
...
If-Modified-Since:Thu, 14 Feb 2013 22:31:14 GMT
If-None-Match:"df739f00c5053d12ef3c625ad6b0fd08"
...

你瞧——服务器返回一个 304 Not modified 响应,你的 HTTP 客户端将从其缓存中提取响应:

304 Not Modified

因此,GitHub API 正确地进行了 HTTP 缓存,您应该使用它。当然,您还必须使用支持 HTTP 缓存的 HTTP 客户端。最好的是,如果您收到 304 Not modified 响应 - GitHub 不会减少您剩余的 API 调用配额。请参阅:https ://docs.github.com/en/rest/overview/resources-in-the-rest-api#conditional-requests

GitHub API 还设置了Cache-Control: private, max-age=60标头,因此您有 60 秒的新鲜度——这意味着对相同资源的请求间隔不到 60 秒甚至不会发送到服务器。

您关于对资源使用单个条件 GET 请求的推理,如果 repo 中的任何内容发生更改,肯定会更改(例如,显示 HEAD sha 的资源)听起来很合理 - 因为如果该资源没有更改,那么您不会不必检查单个文件,因为它们肯定没有改变。

于 2013-02-15T08:40:13.353 回答