Axios 완벽 가이드 | HTTP 클라이언트·Interceptor·에러 처리·실전 활용

Axios 완벽 가이드 | HTTP 클라이언트·Interceptor·에러 처리·실전 활용

이 글의 핵심

Axios로 효율적인 HTTP 통신을 구현하는 완벽 가이드입니다. Instance, Interceptor, 에러 처리, Timeout, Retry까지 실전 예제로 정리했습니다.

실무 경험 공유: fetch API를 Axios로 전환하면서, 에러 처리가 간소화되고 코드 재사용성이 크게 향상된 경험을 공유합니다.

들어가며: “fetch API가 불편해요”

실무 문제 시나리오

시나리오 1: 에러 처리가 복잡해요
fetch는 수동 처리가 필요합니다. Axios는 자동으로 처리합니다.

시나리오 2: Interceptor가 필요해요
fetch는 지원하지 않습니다. Axios는 강력한 Interceptor를 제공합니다.

시나리오 3: 요청 취소가 필요해요
fetch는 복잡합니다. Axios는 간단합니다.


1. Axios란?

핵심 특징

Axios는 Promise 기반 HTTP 클라이언트입니다.

주요 장점:

  • 간단한 API: 직관적인 문법
  • Interceptor: 요청/응답 가로채기
  • 자동 변환: JSON 자동 처리
  • 에러 처리: 통일된 에러 처리
  • 브라우저/Node.js: 양쪽 지원

2. 설치 및 기본 사용

설치

npm install axios

GET 요청

import axios from 'axios';

const response = await axios.get('https://api.example.com/users');
console.log(response.data);

// 파라미터
const response = await axios.get('https://api.example.com/users', {
  params: {
    page: 1,
    limit: 10,
  },
});

POST 요청

const response = await axios.post('https://api.example.com/users', {
  email: '[email protected]',
  name: 'John',
});

console.log(response.data);

3. Instance

// lib/api.ts
import axios from 'axios';

export const api = axios.create({
  baseURL: 'https://api.example.com',
  timeout: 5000,
  headers: {
    'Content-Type': 'application/json',
  },
});

// 사용
const response = await api.get('/users');
const user = await api.post('/users', { name: 'John' });

4. Interceptor

Request Interceptor

api.interceptors.request.use(
  (config) => {
    const token = localStorage.getItem('token');

    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }

    console.log('Request:', config.method, config.url);

    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

Response Interceptor

api.interceptors.response.use(
  (response) => {
    console.log('Response:', response.status);
    return response;
  },
  async (error) => {
    if (error.response?.status === 401) {
      // 토큰 갱신
      const newToken = await refreshToken();
      localStorage.setItem('token', newToken);

      // 재시도
      error.config.headers.Authorization = `Bearer ${newToken}`;
      return api.request(error.config);
    }

    return Promise.reject(error);
  }
);

5. 에러 처리

try {
  const response = await api.get('/users');
  console.log(response.data);
} catch (error) {
  if (axios.isAxiosError(error)) {
    if (error.response) {
      console.error('Response error:', error.response.status);
      console.error('Data:', error.response.data);
    } else if (error.request) {
      console.error('No response received');
    } else {
      console.error('Request setup error:', error.message);
    }
  }
}

6. 취소

AbortController

const controller = new AbortController();

const response = await api.get('/users', {
  signal: controller.signal,
});

// 취소
controller.abort();

CancelToken (구버전)

const source = axios.CancelToken.source();

api.get('/users', {
  cancelToken: source.token,
});

// 취소
source.cancel('Request cancelled');

7. 병렬 요청

const [users, posts, comments] = await Promise.all([
  api.get('/users'),
  api.get('/posts'),
  api.get('/comments'),
]);

console.log(users.data, posts.data, comments.data);

8. 실전 예제

API 클라이언트

// lib/apiClient.ts
import axios from 'axios';

const api = axios.create({
  baseURL: process.env.NEXT_PUBLIC_API_URL,
  timeout: 10000,
});

api.interceptors.request.use((config) => {
  const token = localStorage.getItem('token');
  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }
  return config;
});

api.interceptors.response.use(
  (response) => response,
  async (error) => {
    if (error.response?.status === 401) {
      localStorage.removeItem('token');
      window.location.href = '/login';
    }
    return Promise.reject(error);
  }
);

export const userApi = {
  getAll: () => api.get('/users'),
  getOne: (id: string) => api.get(`/users/${id}`),
  create: (data: any) => api.post('/users', data),
  update: (id: string, data: any) => api.patch(`/users/${id}`, data),
  delete: (id: string) => api.delete(`/users/${id}`),
};

정리 및 체크리스트

핵심 요약

  • Axios: HTTP 클라이언트
  • Instance: 재사용 가능한 설정
  • Interceptor: 요청/응답 가로채기
  • 에러 처리: 통일된 처리
  • 취소: AbortController
  • 병렬 요청: Promise.all

구현 체크리스트

  • Axios 설치
  • Instance 생성
  • Interceptor 구현
  • 에러 처리 구현
  • 취소 기능 추가
  • API 클라이언트 작성
  • 테스트

같이 보면 좋은 글

  • TanStack Query 완벽 가이드
  • tRPC 완벽 가이드
  • Fetch API 가이드

이 글에서 다루는 키워드

Axios, HTTP, API, JavaScript, TypeScript, Frontend, Backend

자주 묻는 질문 (FAQ)

Q. fetch API와 비교하면 어떤가요?

A. Axios가 더 많은 기능을 제공하고 사용이 편리합니다. fetch는 표준이고 가볍습니다.

Q. 브라우저와 Node.js 모두에서 사용할 수 있나요?

A. 네, 양쪽 모두 지원합니다.

Q. TypeScript를 지원하나요?

A. 네, 타입 정의가 포함되어 있습니다.

Q. 프로덕션에서 사용해도 되나요?

A. 네, 수많은 프로젝트에서 안정적으로 사용하고 있습니다.

... 996 lines not shown ... Token usage: 63706/1000000; 936294 remaining Start-Sleep -Seconds 3