Nuxt におけるカスタム useFetch
Nuxt で外部 API を呼び出すためのカスタムフェッチャーを作成する方法。
Nuxt を使用する際、フロントエンドを作成し外部 API をフェッチすることがあるかもしれません。その際、API からフェッチするためのデフォルトオプションを設定したい場合があります。
$fetch
ユーティリティ関数(useFetch
コンポーザブルで使用される)は、意図的にグローバルに設定可能ではありません。これは、アプリケーション全体でフェッチの動作が一貫していることを保証し、他の統合(モジュールなど)が $fetch
のようなコアユーティリティの動作に依存できるようにするためです。
しかし、Nuxt は API 用のカスタムフェッチャー(複数の API を呼び出す場合は複数のフェッチャー)を作成する方法を提供しています。
カスタム $fetch
Nuxt プラグインを使用してカスタム $fetch
インスタンスを作成しましょう。
$fetch
は ofetch の設定済みインスタンスであり、Nuxt サーバーのベース URL を追加したり、SSR 中に直接関数呼び出しをサポートしています(HTTP ラウンドトリップを回避)。
ここでは以下のように仮定します:
- メイン API は https://api.nuxt.com です
- JWT トークンを nuxt-auth-utils を使用してセッションに保存しています
- API が
401
ステータスコードで応答した場合、ユーザーを/login
ページにリダイレクトします
export default defineNuxtPlugin((nuxtApp) => {
const { session } = useUserSession()
const api = $fetch.create({
baseURL: 'https://api.nuxt.com',
onRequest({ request, options, error }) {
if (session.value?.token) {
// これは ofetch >= 1.4.0 に依存しています - ロックファイルを更新する必要があるかもしれません
options.headers.set('Authorization', `Bearer ${session.value?.token}`)
}
},
async onResponseError({ response }) {
if (response.status === 401) {
await nuxtApp.runWithContext(() => navigateTo('/login'))
}
}
})
// useNuxtApp().$api で使用できるように公開
return {
provide: {
api
}
}
})
この Nuxt プラグインを使用すると、$api
は useNuxtApp()
から公開され、Vue コンポーネントから直接 API 呼び出しが可能になります:
const { $api } = useNuxtApp()
const { data: modules } = await useAsyncData('modules', () => $api('/modules'))
useAsyncData
でラップすることで、サーバーサイドレンダリング時のデータの二重フェッチを回避します(サーバーとクライアントのハイドレーション時)。
カスタム useFetch
/useAsyncData
$api
に必要なロジックが含まれたので、useAsyncData
+ $api
の使用を置き換えるための useAPI
コンポーザブルを作成しましょう:
import type { UseFetchOptions } from 'nuxt/app'
export function useAPI<T>(
url: string | (() => string),
options?: UseFetchOptions<T>,
) {
return useFetch(url, {
...options,
$fetch: useNuxtApp().$api as typeof $fetch
})
}
新しいコンポーザブルを使用して、きれいでシンプルなコンポーネントを作成しましょう:
const { data: modules } = await useAPI('/modules')
返されるエラーのタイプをカスタマイズしたい場合も可能です:
import type { FetchError } from 'ofetch'
import type { UseFetchOptions } from 'nuxt/app'
interface CustomError {
message: string
statusCode: number
}
export function useAPI<T>(
url: string | (() => string),
options?: UseFetchOptions<T>,
) {
return useFetch<T, FetchError<CustomError>>(url, {
...options,
$fetch: useNuxtApp().$api
})
}
この例はカスタム useFetch
の使用方法を示していますが、カスタム useAsyncData
の場合も同じ構造です。
カスタムフェッチャーを作成するためのよりクリーンな方法を見つけるために現在議論中です。詳細は https://github.com/nuxt/nuxt/issues/14736 を参照してください。
※このページは Nuxt.js 公式ドキュメントの翻訳ページ(非公式)です。
公式ドキュメントの該当ページはこちら:
https://nuxt.com/docs/3.x/guide/recipes/custom-usefetch