TypeScript

[Next.js] HTTP 요청 구현하기 : fetch vs axios

코샵 2025. 1. 24. 10:48
반응형

기본적인 fetch 사용법

브라우저 내장 fetch API는 별도의 설치 없이 HTTP 요청을 처리할 수 있는 가장 기본적인 방법입니다. Next.js 13 이상에서는 서버 컴포넌트에서도 fetch를 기본적으로 지원합니다.

// 기본적인 GET 요청
async function fetchUsers() {
  const response = await fetch('https://api.example.com/users');
  const data = await response.json();
  return data;
}

// POST 요청 예제
async function createUser(userData) {
  const response = await fetch('https://api.example.com/users', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(userData)
  });
  return response.json();
}

fetch API는 간단하고 직관적이지만, 에러 처리나 요청 취소 등 고급 기능을 사용할 때는 추가적인 코드가 필요합니다.

axios를 활용한 고급 HTTP 요청

axios는 더 풍부한 기능과 편리한 인터페이스를 제공하는 HTTP 클라이언트 라이브러리입니다.

import axios from 'axios';

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

// GET 요청
async function fetchUsers() {
  try {
    const { data } = await api.get('/users');
    return data;
  } catch (error) {
    console.error('Error fetching users:', error.message);
    throw error;
  }
}

// POST 요청
async function createUser(userData) {
  try {
    const { data } = await api.post('/users', userData);
    return data;
  } catch (error) {
    console.error('Error creating user:', error.message);
    throw error;
  }
}

Next.js 서버 컴포넌트에서의 데이터 페칭

Next.js 13 이상에서는 서버 컴포넌트에서 자동적인 요청 중복 제거와 캐싱을 제공합니다.

// app/users/page.tsx
async function UsersPage() {
  // 이 fetch 요청은 자동으로 캐싱됩니다
  const users = await fetch('https://api.example.com/users', {
    next: { revalidate: 3600 } // 1시간마다 재검증
  }).then(res => res.json());

  return (
    <div>
      {users.map(user => (
        <div key={user.id}>{user.name}</div>
      ))}
    </div>
  );
}

fetch와 axios의 주요 차이점

에러 처리

// fetch의 경우
async function fetchWithError() {
  try {
    const response = await fetch('https://api.example.com/data');
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    const data = await response.json();
    return data;
  } catch (error) {
    console.error('Error:', error);
  }
}

// axios의 경우
async function axiosWithError() {
  try {
    const { data } = await axios.get('https://api.example.com/data');
    return data;
  } catch (error) {
    if (error.response) {
      console.error('Server responded with:', error.response.status);
    }
  }
}

axios는 HTTP 에러 상태를 자동으로 감지하고 reject하지만, fetch는 네트워크 오류에 대해서만 reject합니다.

 

인터셉터 활용 (axios)

axios의 강력한 기능 중 하나는 요청과 응답을 가로채서 수정할 수 있는 인터셉터입니다.

// axios 인터셉터 설정
const api = axios.create({
  baseURL: 'https://api.example.com'
});

// 요청 인터셉터
api.interceptors.request.use(
  config => {
    // 요청 보내기 전 수행할 작업
    const token = localStorage.getItem('token');
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  error => {
    return Promise.reject(error);
  }
);

// 응답 인터셉터
api.interceptors.response.use(
  response => response,
  error => {
    if (error.response?.status === 401) {
      // 인증 에러 처리
      localStorage.removeItem('token');
      window.location.href = '/login';
    }
    return Promise.reject(error);
  }
);

선택 가이드라인

fetch 사용이 적합한 경우 axios 사용이 적합한 경우
간단한 HTTP 요청만 필요할 때 복잡한 API 통신이 필요할 때
Next.js의 자동 캐싱과 재검증 기능을 활용하고 싶을 때 인터셉터를 통한 요청/응답 처리가 필요할 때
번들 사이즈를 최소화하고 싶을 때 자동화된 에러 처리가 필요할 때
  요청 취소나 타임아웃 설정이 필요할 때 

 

이러한 차이점들을 고려하여 프로젝트의 요구사항에 맞는 도구를 선택하시면 됩니다. 작은 프로젝트라면 fetch만으로도 충분할 수 있지만, 큰 규모의 프로젝트에서는 axios의 추가 기능들이 유용할 수 있습니다.