0
Deno Web Cacheを使ってGitHub APIへのリクエストをキャッシュする
2024-12-23

DenoのWeb Cache APIが使えるようになっていた

待望っちゃ待望なのでどこかで使ってみたいなと思っていたがちょうどGitHubのコントリビューションを過去数年分さかのぼって1つの画像にまとめるAPIの記事で紹介したような機能に使えそうということでやってみた

Web Cache API

Introducing Web Cache API support on Deno Deploy

Denoから外部APIへのリクエストのキャッシュ例があったのでケースとしてはまんまこのパターン

対象機能

参照記事の実装の概要や仕様

  • GitHub GraphQLのクエリで受けたユーザーのコントリビューションデータ(草のもととなるデータ)を取得
  • レスポンスとして、fromtoで指定した最大366日分(ほぼ1年分)のコントリビューションデータが返ってくる
  • 複数年にわたりデータを取得する必要がある
    • 現在だと最大16年ほどなので最大16回ほどAPIへリクエストが発生する
    • 対象データはコントリビューションのデータなので過去データは基本的には変わらない(はず)
  • コントリビューションデータへクエリする際のノード消費量は1
    • ratelimit的には5000/1時間の制限がある

経緯

過去データに対してのAPIリクエストはCacheを使いAPIリクエスト自体発生しないようにすることでパフォーマンスの改善を狙う

最初実装を考えたときに最初からキャッシュするか迷ったがノード消費量1だしアクセスが結構あったとしてもratelimitに引っかかる心配はほぼない

なのでいったんは都度リクエストで大丈夫と判断してリリースした

実際にリリースしたらratelimitに引っかかることはないが期間が長くなると遅いなっていうのが正直なところだった

Slackとかに貼った場合、一定時間が経過するとリクエストが飛ぶっぽいのでそのたびに時間が掛かる、その都度遅く感じるっていうのが普通にストレス

ということでさっそくWebキャッシュを導入する

実装

  • contributions.ts
-const getContributions = async (user: string, from?: string, to?: string) => {
+const getContributions = async (useCache: boolean, user: string, from?: string, to?: string) => {
+  const cache = await caches.open("gh-api");
+
+  const cacheKey = `${API_URL}/${user}/${from}/${to}`;
+  const cached = await cache.match(cacheKey);
+  if (useCache && cached) return await cached.json();
+
   const token = Deno.env.get("GH_READ_USER_TOKEN");
   const query = `
     query($user:String! $from:DateTime $to:DateTime) {

.....
.....
.....

     body: JSON.stringify(json),
   });

-  return await res.json();
+  if (useCache && res.ok && from && to) {
+    await cache.put(cacheKey, res.clone());
+  }
+
+  return await res.json();
 };

cacheの使用箇所はこんな感じ

cacheKeyはURL形式にする必要があった(http,httpsで始まる文字列)ため、APIのエンドポイントURL+ユニークの単位を担保できるようパラメータをつなげた文字列にした

useCacheでcacheを使うかのフラグを外から渡すようにした

これは、今年のコントリビューション数は時間の経過で変化する可能性が高く、cacheは使わず都度リクエストを送るため渡す側で判断してコントロールするようにした

結果

アクセスログとか取っていなく、レスポンス時間を実測していないのは非常に残念ではあるが、実際12年とか13年とかの期間を試してみたら明らかに差が出た

Cache導入前は普通に体感30秒くらいかな?は時間かかっていたが一度アクセスしたあとは1~3秒くらいで返ってくる(体感)

0

Profile

swfz
swfz
日々学んだことを残していく
Today I Learned
コード片置き場

Account

RSS

Powered by Pixela
© 2024. swfz