Amplify Cache の有効期限について理解する

Amplify Librariesには Cacheという機能があります。

Webアプリケーションでこの機能を使うとLocalStorageに任意の値をキャッシュしてくれるとのこと(オプションでSessionStorageにも保存可能です)。

Amplify Libraries経由でキャッシュ機能を使うメリットとしては有効期限を指定できるという点で、

  • アプリケーション全体で共通の有効期限を指定
  • アイテムごとに有効期限

の2パターンの設定が可能です。

アプリケーション全体で共通の有効期限を指定

Cache.configureで defaultTTL を指定することで設定できます。

import { Cache } from 'aws-amplify';

Cache.configure({
   defaultTTL: 60000, // 60秒
 })

このコードではキャッシュの保存期間を60秒に設定しています。

余談ですが、保存先をSessionStorageに切り替える場合もここのオプションでやります。

Cache.configure({
  storage: window.sessionStorage
})

LocalStorageにはこのように保存されます。

new Date(1682719522531) => Sat Apr 29 2023 07:05:22 GMT+0900 (日本標準時)

アイテムごとに有効期限

こちらはキャッシュするアイテムごとに個別の有効期限を設定することのできる機能です。

ドキュメントでも「APIリクエストの結果は10分間キャッシュしたいけど、ユーザー設定とかは1ヶ月くらい保持したいよね?」的なことが書かれています。

アイテムをキャッシュするときのオプションで指定が可能です。

Cache.setItem('comment', comment, {
  expires: Math.floor(expireAt.getTime())
});

公式ドキュメントには以下のような説明が書かれているので少し気になってので詳しく調べてみました。

The expiration time of the cache item in milliseconds.

(僕の英語力の問題かもしれませんが)この expiration timeというのを当初、setItemを起点とした経過時間のように誤読してしまったので 例えば60秒保持したい場合に、TTLと同じように以下のように

Cache.setItem('comment', comment, {
    expires: 60000 // 60秒保持するつもり
 });

のように設定していたのですが、これは誤りでした。 このコードでは登録後すぐに消えてしまいます

実際のコードを確認してみると、以下のようになっています。

const cacheItemOptions: CacheItemOptions = {
...
    expires:
        options && options.expires !== undefined
            ? options.expires
            : this.config.defaultTTL + getCurrTime(),
};

amplify-js/packages/cache/src/BrowserStorageCache.ts github.com

この実装について NotionのAIに尋ねると以下のような答えが返ってきました。

このコードはoptions.expires が未定義でないかをチェックします。options.expires が定義されている場合は、その値を使用します。未定義の場合は、this.config.defaultTTL で保持されているデフォルトの有効期間 (TTL) 値を使用し、getCurrTime() を使用して現在時刻を加算します。

だそうです。 要するに expires はキャッシュの経過時間ではなく、有効期限のUNIXタイムスタンプを指定するものなのですね。

Cache.setItem('comment', comment, {
    expires: new Date(2023, 4, 6).getTime() // 2023.5.5(JST) に無効になる
 });

検証

簡単なアプリケーションを書いて動きを見てみました。

github.com

youtu.be