🍩

Nuxt3のgetCachedDataによるキャッシュ戦略

2024/01/29に公開

Nuxt3.8でuseFetchgetCachedDataという機能が追加されました。

https://nuxt.com/blog/v3-8#️-data-fetching-improvements

これまでのNuxt3のuseFetchではstale-while-revalidateというキャッシュ戦略に基づいており情報取得までの短い期間のキャッシュは保存して返却されてくれますが、API通信そのものをキャッシュすることはできませんでした。

Nuxt3.8より前でもuseStateを利用すれば無理やりキャッシュすることもできますがスマートな方法とは言えません

useStateを利用したAPIキャッシュ

以下のように useStateに同一キーを与え、初期値にはuseFetchの返り値を指定します。


const { value: data1 } = useState('api_cache_key_xxx', () =>  {
  const response = useFetch('/api/lazy')
  return response.data
});

const { value: data2 } =  useState('api_cache_key_xxx', () =>  {
  const response = useFetch('/api/lazy')
  return response.data
});

const { value: data3 } =  useState('api_cache_key_xxx', () =>  {
  const response = useFetch('/api/lazy')
  return response.data
});

const { value: data4 } =  useState('api_cache_key_xxx', () =>  {
  const response = useFetch('/api/lazy')
  return response.data
});

そうすることで初回のみAPIアクセスを行い、2回目以降はuseStateに保存されたAPIキャッシュの内容を返却してくれるようになります。

response.dataはリアクティブなデータのため非同期通信が終わるまではnullですが、取得が終わったタイミングですべてに反映されます。

サンプルはすこし冗長なコードですが、実際はcomposableで上手に共通化して利用します。

すこし無理やりな感じもしますね。

Nuxt3.8では標準でgetCachedDataという機能が追加されよりスマートなキャッシュが可能になりました。

getCachedDataを利用したAPIキャッシュ

getCachedDataを利用するにはkeyオプションで共通のキャッシュを利用したい通信に同一の名前を付けます。付けない場合はURLなどから自動で命名されます。

getCachedDataメソッドにはnuxtApp.payload.data[key] || nuxtApp.static.data[key]を返却値に指定します。

これはAPIのキャッシュデータの格納場所でキャッシュデータがヒットすればキャッシュデータが返却され通信は行わずにキャッシュデータを利用するようになります。

const nuxtApp = useNuxtApp()

const { data:data1 } = await useFetch('/api/lazy', {
    key:'api_cache_key_xxx',
    getCachedData: (key) =>  nuxtApp.payload.data[key] || nuxtApp.static.data[key]
})

const { data:data2 } = await useFetch('/api/lazy', {
    key:'api_cache_key_xxx',
    getCachedData: (key) =>  nuxtApp.payload.data[key] || nuxtApp.static.data[key]
})

const { data:data3 } = await useFetch('/api/lazy', {
    key:'api_cache_key_xxx',
    getCachedData: (key) =>  nuxtApp.payload.data[key] || nuxtApp.static.data[key]
})

const { data:data4 } = await useFetch('/api/lazy', {
    key:'api_cache_key_xxx',
    getCachedData: (key) =>  nuxtApp.payload.data[key] || nuxtApp.static.data[key]
})

こちらも実際はcomposableで上手に共通化して利用するとよいでしょう。

useStateと比較すると1階層浅くなっているのでエラーハンドリング等がやりやすくなっています。

結論

Nuxt3のキャッシュ戦略を考える場合には、APIレスポンスの生存期間に応じてデフォルトのstale-while-revalidateを採用するか、getCachedDataを利用したキャッシュを採用するか考慮したほうがよいでしょう。

株式会社トゥーアール

Discussion