-
[ Project ] RTK-Query에 Axios 입히기Project 2023. 9. 4. 21:29
- RTK-Query에 Axios 를 ?
RTK-Query란 Redux Toolkit 내의 포함되어 있고 데이터 패칭 및 서버 상태 관리를 도와주는 기능을 제공합니다.
기본적으로 fetch를사용하여 HTTP 통신을 합니다.
현재 진행 중인 프로젝트에서 RTK-Query를 사용 중인데, API 요청에 일괄 처리가 필요한 두 가지의 이유가 있습니다.
1. 모든 요청 헤더에 토큰이 필요.
2. accessToken토큰이 만료되었을 경우, 토큰 재발급하고 갱신된 토큰을 헤더에 설정하고 재요청.
1번 문제 같은 경우, RTK-Query의 prepareHeaders 요청 헤더를 수정할 수 있습니다.
하지만 API slice마다 헤더에 토큰을 넣어주는 중복되는 코드도 발생할뿐더러
2번 문제같은 경우는 바로 해결할 수 있는 기능이 Fetch API에는 존재하지 않습니다.
그리하여, 위 두 가지 문제의 해결책인 Axios Interceptor를 활용하기 위해 RTK-Query에 Axios BaseQuery를 적용했습니다.
- RTK-Query에 Axios 적용하기
공식문서 우측 상단 Search에 'Axios baseQuery'를 검색해 주세요. import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react' import type { Pokemon } from './types' export const pokemonApi = createApi({ reducerPath: 'pokemonApi', baseQuery: fetchBaseQuery({ baseUrl: 'https://pokeapi.co/api/v2/' }), endpoints: (builder) => ({ getPokemonByName: builder.query<Pokemon, string>({ query: (name) => `pokemon/${name}`, }), }), }) export const { useGetPokemonByNameQuery } = pokemonApi
공식 문서에 있는 RTK-Query의 기본 템플릿 코드입니다.
baseQuery: fetchBaseQuery({ baseUrl: 'https://pokeapi.co/api/v2/' })
baseQuery는 RTK Query에서 실제 네트워크 요청을 수행하는 함수를 정의하는 데 사용되는 곳입니다.
기본적으로 RTK Query는 fetch를 사용하여 API 호출을 수행하기에 fetchBaseQuery를 사용하는 것을 확인할 수 있습니다.
즉, fetchBaseQuery자리에 Axios로 통신하도록 코드를 구현하여 적용하면 됩니다.
Customizing axiosBaseQuery 공식문서에서 Examples - baseQuery / Axios baseQuery 부분을 참고.
공식문서를 참고하면 어렵지 않게 만들 수 있습니다.
axios instance를 만들어줬기 때문에 baseUrl 생략하고 import한 instance 사용했습니다.
import type { BaseQueryFn } from '@reduxjs/toolkit/query'; import type { AxiosRequestConfig, AxiosError } from 'axios'; import instance from './instance'; const axiosBaseQuery = (): BaseQueryFn< { url: string; method: AxiosRequestConfig['method']; data?: AxiosRequestConfig['data']; params?: AxiosRequestConfig['params']; }, unknown, unknown > => async ({ url, method, data, params }) => { try { const result = await instance({ url, method, data, params }); return { data: result.data }; } catch (axiosError) { let err = axiosError as AxiosError; return { error: { status: err.response?.status, data: err.response?.data || err.message, }, }; } }; export default axiosBaseQuery;
axiosBaseQuery를 API splice에 적용
import { createApi } from "@reduxjs/toolkit/query/react"; import axiosBaseQuery from "./axiosBaseQuery"; const END_POINT = "api/member"; export const memberApi = createApi({ baseQuery: axiosBaseQuery(), reducerPath: "memberApi", tagTypes: ["Member"], endpoints: (builder) => ({ // 모든 멤버 정보 가져오기 getAllMembers: builder.query({ query: () =>({ url:`${END_POINT}/get/v1/all-members`, method:"GET" }), providesTags: [{type: "Member"}] }),
- 개선점
Axios를 적용함으로써 이점은 명확했습니다.
1. 기존에 각 api slice마다 prepareHeaders에 토큰을 넣어주는 코드를 interceptors.request를 통해 집약적으로 관리할 수 있습니다.
좌측은 fetchBaseQuery를 사용할 때의 코드입니다. 우측에서는 prepareHeaders에 해당하는 코드가 interceptors.request에서 관리하여 반복되는 코드를 줄일 수 있습니다.
2. Axios Interceptor를 활용하여 토큰 만료 시 요청을 가로채어, 에러 핸들링을 용이하게 할 수 있습니다.
Axios 적용 완료했으니, 이어서 Axios Interceptor 활용 글을 작성하겠습니다 !
'Project' 카테고리의 다른 글
[ Project ] FormData ( File과 Json data를 함께 ) (0) 2023.10.19 [ Project ] 컴포넌트 설계에 대한 고민 (Feat. 합성 컴포넌트) (1) 2023.09.10 [ Project ] Axios Interceptor 활용하기 (0) 2023.09.06 [ Project ] React 재사용 버튼 컴포넌트 만들기 (0) 2023.09.01 [ Project ] Next.js 13 다크모드 적용기 (0) 2023.08.30