Axios
; node.js와 브라우저를 위한 Promise 기반 HTTP 클라이언트
- Axios를 사용하기에 앞서서, 우리가 사용할 Axios의 instance를 만들어줄 수 있습니다.
- 저희는 src > apis > _axios > instance.ts에 instance를 생성하였습니다.
1. instace 생성
import axios from 'axios';
import { CONFIG } from '@config';
...
const instance = axios.create({
baseURL: CONFIG.API_BASE_URL,
});
CONFIG.API_BASE_URL은 저희 서버의 uri입니다.
2. instance.interceptors
; then 또는 catch로 처리되기 전에 요청과 응답을 가로챌 수 있습니다.
2.1 instance.interceptors.request.use : 요청 api에 header 담기
instance.interceptors.request.use(
(config) => {
const token = getToken();
config.headers = {
...config.headers,
Authorization: token.accessToken,
};
return config;
},
(error) => {
Promise.reject(error);
},
);
- 저희는 JWT를 사용해서, 모든 API에 Access Token을 담아서 보내주어야 했습니다.
- localStorge에 저장된 token을 가져와 header에 담아줍니다.
2.2 instance.interceptors.reponse.use : 응답 response에 대한 에러핸들링 및 처리
instance.interceptors.response.use(
(response) => {
return response;
},
async (error) => {
const { config: originalRequest, response } = error;
const { status, data } = response;
const isUnAuthError = status === 401;
const isNotFoundError = status === 404;
const isDuplicateError = status === 409;
if (isNotFoundError) {
return Promise.reject(error.response.data);
}
if (isDuplicateError) {
return Promise.reject(error.response.data);
}
if (isUnAuthError) {
if (data?.code === 'TOKEN_INVALID') {
if (CONFIG.ENV === 'development') {
alert('세션이 만료되었습니다. 다시 로그인해 주시기 바랍니다.');
window.location.href = `${CONFIG.LOCAL}/auth/login`;
} else if (CONFIG.ENV === 'production') {
alert('세션이 만료되었습니다. 다시 로그인해 주시기 바랍니다.');
window.location.href = `${CONFIG.DOMAIN}/auth/login`;
}
return;
}
if (data?.code === 'TOKEN_EXPIRED') {
setToken({
accessToken: '',
refreshToken: getToken().refreshToken,
roles: getToken().roles,
});
const { accessToken } = await refreshToken();
setToken({
accessToken,
refreshToken: getToken().refreshToken,
roles: getToken().roles,
});
return instance.request(originalRequest);
}
return Promise.reject(error.response.data);
}
},
);
- 정상적으로(status=2xx) 응답이 왔다면 response를 그대로 return 해줍니다.
- 그렇지 못하다면, error의 status와 code에 따라 각 상황에 맞는 에러 핸들링을 해줍니다.
- status = 401 : 권한 없음(isUnAuthError) 에러 처리
- code = TOKEN_INVALIED : RefreshToken 혹은 AccessToken이 잘못된 경우로, 로그인 페이지로 redirect 시켜줍니다.
- code = TOKEN_EXPIRED : AccessToken이 만료된 경우로, Refresh Token으로 서버 측에 Access Token을 재요청합니다.
- status = 404 : 페이지 찾지 못함(isNotFoundError) 에러 처리
- status = 409 : 중복(isDuplicateError) 에러 처리
- 각 케이스 별 에러 처리를 해주었습니다.
- status = 401 : 권한 없음(isUnAuthError) 에러 처리
지금까지 instance를 만들었습니다. 이제는 instance를 그냥 가져다가 쓰면 됩니다.
3 생성한 instance 사용하기
axios> home> homeApi.ts
import instance from '@apis/_axios/instance';
...
async getPastAuctionList(): Promise<AuctionList[]> {
const { data } = await instance('/auction/period-over');
return data;
}
위에서 생성한 instance를 불러와 사용합니다. 헤더에 담겨야 하는 uri와 AccessToken은 위의 instance에서 설정을 해두어서 자동으로 localStorage에 있는 AccessToken을 가져와 담아 전송을 합니다.
Axios는 instace 만드는 법을 익히기 전과 후로 나뉘는 것 같습니다. instance를 만들어 일괄적으로 AccessToken과 destination의 uri를 설정해 주는 순간 코드가 매우 간결해지고, 그만큼 코드 작성이 쉬워집니다. 코드 작성이 쉬워지면 에너지가 적게 들고, 실수가 적어지고, 그렇게 프로젝트의 완성도가 올라갑니다.
이래서 라이브러리는 깊이 있게 공부해야 하는 것 같다는 것을 느꼈습니다. 앞으로 프로젝트를 진행할 때 내가 이 프로젝트에서 사용하고 있는 라이브러리만큼은 '최대한 깊이 있게 공부해야겠다'는 마음으로 공부를 해야겠다고 다짐했습니다.
마지막으로 Axios instance 구현한 github 링크 공유하고 마칠게요 !
https://github.com/Att-ies/frontend/blob/dev/src/apis/_axios/instance.ts
'개발 일지 > 개발 일지' 카테고리의 다른 글
[개발 일지] React성능 최적화 (2) : React Query의 캐싱 기능 (1) | 2023.05.05 |
---|---|
[개발 일지] React성능 최적화 (1) : React.memo로 사용자 경험 개선하기 (0) | 2023.05.03 |
[개발 일지] Next.js에서 접근성 향상하기 (접근성 점수 84점 -> 97점 향상시킨 썰) (0) | 2023.04.27 |
[개발 일지] React Query - Custom Hook 만들기 (+Typescript) (0) | 2023.04.13 |
[개발 일지] JWT + 소셜 로그인을 정복해보자 (React + Spring Boot, Kakao Login, Naver Login) (0) | 2023.04.11 |
[개발 일지] Intersection Observer API & react-query를 이용한 무한스크롤 구현 (0) | 2023.02.28 |
[개발 일지] Suspense를 이용하여 모든 api에 Loading 화면을 설정하자 (NextJS, Suspense) (0) | 2023.02.18 |
[개발 일지] 채팅 기능을 구현해보자 (Websocket, Stomp, SockJS) (0) | 2023.02.10 |