• HTTP 클라이언트 라이브러리
  • 클라이언트(브라우저)에서 API 서버(또는 백엔드)로 HTTP 요청 보낼 때 사용
  • 서버 API를 호출하는 역할
    => HTTP 요청용으로 fetch와 같은 기능

✅ 1. Axios와 fetch의 주요 차이점 요약

항목fetch (기본 내장 API)axios (외부 라이브러리)
내장 여부✅ 브라우저 내장 (추가 설치 불필요)❌ 설치 필요 (npm install axios)
응답 상태 처리직접 res.ok(response status가 200~299인지 true/false), res.status(응답 상태 코드 ex)200,400...) 확인오류 시 자동으로 catch로 이동
JSON 파싱res.json() 직접 호출해야 함 ex) const data = await res.json();응답을 받아서 자동으로 res.data에 JSON 파싱됨
요청 취소AbortController 사용해야 함CancelToken 또는 AbortController 사용
기본 설정없음baseURL, 공통 headers 설정 가능
요청/응답 인터셉터❌ 불가능✅ interceptors 지원
구형 브라우저 지원❌ 필요 시 polyfill 필요✅ 내부적으로 대응됨

✅ 인터셉터는 왜 필요할까?

"중간에서 가로채서 처리하는 로직"

  • 모든 요청에 토큰을 자동으로 추가하고 싶다
  • 응답에서 공통 에러 처리(예: 토큰 만료, 401 등)를 하고 싶다
  • 요청을 보내기 전 데이터를 변형하거나, 응답을 가공하고 싶다
  • 인터셉터는 한 곳에서 한번만 설정해서 모든 API 요청과 응답을 처리해야함
      // 요청 인터셉터
      this.instances[BASE_URL].interceptors.request.use(
        (config) => {
          // 해당 인스턴스에 대한 토큰이 있을 경우 헤더에 추가
          const token = this.tokenMap[BASE_URL];
          if (token) {
            config.headers['x-admin-auth-token'] = token;
          }
          return config;
        },
        (error) => {
          return Promise.reject(error);
        },
      );

      // 응답 인터셉터
      this.instances[baseURL].interceptors.response.use(
        (response) => {
          return response;
        },
        (error) => {
          const unauthorized = error.status === 401;
          console.log('unauthorized', error);
          console.log('unauthorized', baseURL);
          if (unauthorized) {
            this.refreshToken('/api/1.0/admin/user/refreshToken');
          }
          return Promise.reject(error);
        },
      );

✅ res.status

상태 코드의미
200OK (성공)
201Created (생성됨)
400Bad Request (잘못된 요청)
401Unauthorized (인증 실패)
403Forbidden (접근 금지)
404Not Found (경로 없음)
500Internal Server Error (서버 오류)

실무에서 더 많이 쓰는 건?
📊 axios가 실무에서 더 많이 사용됨

  • 팀 프로젝트에서 응답 인터셉터를 사용해 로그인 토큰 자동 처리 등 공통 로직 관리가 가능
  • 에러 처리 구조가 직관적
  • 백엔드 API와 연동할 때 반복되는 설정 (baseURL, withCredentials, headers 등) 관리가 용이

실제 사용 예시

1. fetch

  const onSubmit = async (data: LoginFormInputs) => {
    try {
      const res = await fetch("/api/auth/login", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          userId: data.userId,
          password: data.password,
        }),
      });

      if (!res.ok) {
        const errorData = await res.json();
        showToast({
          type: ToastMode.ERROR,
          action: "SAVE",
          content: errorData.error || "로그인에 실패했습니다.",
        });
        return;
      }

      const result = await res.json();
      login({ userId: result.userId }); // 필요 시 토큰이나 기타 정보도 저장
      router.replace("/dashboard/kanban");
    } catch (error) {
      showToast({
        type: ToastMode.ERROR,
        action: "SAVE",
        content: "서버와 통신 중 오류가 발생했습니다.",
      });
      console.error(error);
    }
  };

2. Axios

  const onSubmit = async (data: LoginFormInputs) => {
    try {
      const res = await axios.post("/api/auth/login", {
        userId: data.userId,
        password: data.password,
      });

      const result = res.data;
      login({ userId: result.userId }); // 필요 시 토큰이나 기타 정보도 저장
      router.replace("/dashboard/kanban");
    } catch (error) {
      const message =
        error.response?.data?.error || "서버와 통신 중 오류가 발생했습니다.";

      showToast({
        type: ToastMode.ERROR,
        action: "SAVE",
        content: message,
      });
      console.error(error);
    }
  };

결론: Axios를 쓰면 요청·응답 처리 코드가 간단해지고, 중복도 줄어들어 관리가 편해짐

profile
단순 사용자가 아닌, 이해하고 만드는 개발자가 되기 위한 기록.

0개의 댓글