[0905] axios interceptor

한별·2024년 9월 14일

스파르타 내배캠 TIL

목록 보기
63/63

한달인턴 프리온보딩 과제 진행 중에 axios에서 반복되는 catch문 코드가 굉장히 신경쓰였다.
사실 oosie 프로젝트 때도 똑같은 문제가 있었는데 그때는 바빠서 눈에 들어오지 않았음.. 시간나면 리팩토링을 진행해야겠다 ^^

이때 알게된 것이 interceptor이다. 이거는 OOSIE 프로젝트 최종 발표일에 세이지의 면접 코치(?)님이 언급하셔서 존재만 알고 있었다. 써보니까 코치님이 이 기능을 좋아하시는 이유를 알겠더라.. 너무 조아ㅏㅏㅏ!!!!!!!


Interceptor란?

axios는 fetch보다 더 다양한 기능을 제공하는 라이브러리이고, 요청과 응답을 가로챌 수 있는 interceptor 기능 또한 제공한다.

docs를 보면 then 또는 catch로 처리되기 전에 요청과 응답을 가로챌수 있다고 한다.

client.interceptors.response.use(
  (response) => response,
  (error) => {
    if (axios.isAxiosError(error)) {
      throw new Error(error.response?.data.message);
    }
    throw error;
  }
);

중복되는 axios 코드 제거하기

다음과 같은 코드를 이용하여 throw 코드를 interceptor로 분리하였다.

이렇게 되면, 아래와 같이 길었던 API 코드들에서

export async function register(data: RegisterType) {
  try {
    const response = await client.post("/register", data);
    return response.data;
  } catch (e) {
    if (axios.isAxiosError(e)) throw new Error(e.response?.data.message);
    throw e;
  }
}

6줄을 줄일 수 있었다.

export async function register(data: RegisterType) {
  const response = await client.post("/register", data);
  return response.data;
}

401 에러 처리

401일때 login으로 리다이렉트하기 위해 interceptor에 switch문을 추가해주었다.

client.interceptors.response.use(
  (response) => {
    return response;
  },
  (error) => {
    if (axios.isAxiosError(error))
      // 추가
      switch (error.response?.status) {
        case 401:
          console.log(401);
          break;
        default:
          throw new Error(error.response?.data.message);
      }
      //
    throw error;
  }
);

근데 navigate를 쓰려고 하니까 컴포넌트 밖이라서 useNavigate를 쓸 수가 없다는 문제가 발생했다.

stack overflow에서 해답을 찾았다.

createBrowserRouter의 리턴값인 router를 export하고 인터셉터가 포함된 파일에서 import 받아서 이렇게 쓰면 가능했다. :D

router.navigate("/login");

참고 자료

axios interceptor로 401 처리하기 | 고광필 | velog
react router v6 navigate outside of components | stack overflow

관련 커밋

refactor: axios interceptor로 api 반복 코드 삭제
feat: 권한별 라우팅 제어

profile
글 잘 쓰고 싶어요

0개의 댓글