Nuxt에서의 Custom useFetch
Nuxt에서 외부 API를 호출하기 위한 커스텀 fetcher를 만드는 방법.
Nuxt를 사용할 때, 프론트엔드를 만들고 외부 API를 가져오며, API에서 가져오는 기본 옵션을 설정하고 싶을 수 있습니다.
$fetch
유틸리티 함수 ( useFetch
컴포저블에서 사용됨)는 의도적으로 전역 설정이 불가능합니다. 이는 애플리케이션 전반에서 가져오기 동작이 일관되게 유지되고, 다른 통합(모듈 등)이 $fetch
와 같은 핵심 유틸리티의 동작에 의존할 수 있도록 하는 것이 중요하기 때문입니다.
그러나 Nuxt는 API에 대한 커스텀 fetcher를 만들 수 있는 방법을 제공합니다 (여러 API를 호출해야 하는 경우 여러 fetcher를 만들 수도 있습니다).
Custom $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에 의존합니다 - lockfile을 새로 고쳐야 할 수도 있습니다.
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
로 감싸면 서버 사이드 렌더링 시 데이터 중복 가져오기를 방지합니다 (서버 및 클라이언트에서의 하이드레이션).
Custom 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
에도 동일하게 적용됩니다.
현재 커스텀 fetcher를 만들 수 있는 더 깔끔한 방법을 찾기 위해 논의 중입니다. 자세한 내용은 https://github.com/nuxt/nuxt/issues/14736를 참조하세요.
※이 페이지는 Nuxt.js 공식 문서의 비공식 번역 페이지입니다.
공식 문서의 해당 페이지는 여기 있습니다:
https://nuxt.com/docs/3.x/guide/recipes/custom-usefetch