본문 바로가기

FE

올바른 HTTP 클라이언트 선택하기 - fetch, Axios, Ky

웹 개발에서 외부 리소스와의 상호 작용을 하기 위한 다양한 HTTP 클라이언트가 존재합니다.

이 글에서는 가장 널리 사용되는  Fetch, Axios, 그리고 Ky를 비교하고, 각 라이브러리의 특징, 장단점, 그리고 적합한 사용 사례를 정리해보았습니다.

1. Fetch

Fetch는 브라우저에 기본 내장된 API로, 별도의 라이브러리 설치 없이 바로 사용할 수 있다는 가장 큰 장점을 가지고 있습니다. Promise 기반으로 작동하며, 간결한 문법으로 비동기 통신을 처리할 수 있습니다.

 

장점:

  • 설치 불필요: 브라우저 내장 API이므로 추가적인 패키지 설치가 필요 없어 번들 크기를 줄이는 데 효과적입니다.
  • 표준 API: 웹 표준을 따르므로 브라우저 환경에서 높은 호환성을 보장합니다.
  • React Query, SWR 연동: 서버 상태 관리 라이브러리와 함께 사용하기에 적합합니다.

단점:

  • 수동 에러 처리: HTTP 에러 상태(404, 500 등)를 자동으로 감지하지 않아 res.ok 속성을 통해 수동으로 에러를 처리해야 합니다.
  • JSON 파싱: 응답 데이터를 사용하기 위해 .json() 메서드를 명시적으로 호출해야 합니다.
  • 기능 부족: 타임아웃, 요청 취소 등의 기능을 직접 구현해야 하는 번거로움이 있습니다.
  • 구형 브라우저 미지원: Node.js 환경에서는 node-fetch와 같은 추가 모듈이 필요합니다.

 

2. Axios

Axios는 브라우저와 Node.js 환경 모두에서 사용할 수 있는 널리 사용되는 HTTP 클라이언트 라이브러리입니다. Fetch보다 풍부한 기능을 제공하며, 실무에서 많은 개발자들에게 사랑받고 있습니다.

 

장점:

  • 자동 JSON 변환: 응답 데이터를 자동으로 JSON으로 파싱해주어 코드가 간결해집니다.
  • 직관적인 에러 처리: HTTP 에러 상태 발생 시 자동으로 예외를 던져 catch 블록에서 쉽게 처리할 수 있습니다.
  • 인터셉터 : 요청 및 응답을 가로채어 공통 로직(예: 토큰 추가, 에러 로깅)을 처리할 수 있어 유지보수성이 뛰어납니다.
  • 다양한 기능: 요청 취소, 타임아웃 설정, 업로드 진행률 표시 등 고급 기능을 기본적으로 제공합니다.
  • 브라우저 호환성: 구형 브라우저를 포함하여 다양한 환경을 지원합니다.

단점:

  • 별도 설치 필요: 외부 라이브러리이므로 설치가 필요하며, 프로젝트 번들 크기가 증가할 수 있습니다.
  • 복잡성: Fetch에 비해 설정이 복잡하고 초기 학습 곡선이 존재할 수 있습니다.

코드 예시 

 

src/shared/api/api-client.ts

 

인스턴스를 생성하고 에러 로깅을 위한 인터셉터를 설정

export const apiClient = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL,
  headers: { 'Content-Type': 'application/json' },
  withCredentials: true, // CORS 요청 시 쿠키 포함
});

apiClient.interceptors.response.use(
  (response) => response,
  (error: AxiosError<BaseResponse<unknown>>) => {
    // 에러 로깅 처리
    if (import.meta.env.DEV) {
      /* ... console.error(method, url, status) ... */
    }
    return Promise.reject(error);
  }
);




src/shared/api/request.ts

request 헬퍼 함수입니다. apiClient를 호출하고, 성공 시 data만 추출하여 반환합니다.

export const request = async <T>(config: RequestConfig): Promise<T> => {
  const { method, url, query, body, headers } = config;

  try {
    const response = await apiClient.request<BaseResponse<T>>({
      method, url, params: query, data: body, headers,
    });

    // 성공하면  실제 data만 반환
    return response.data.data;

  } catch (error: unknown) {
    if (!isAxiosError(error)) throw error;

    // 실패하면 서버 메시지 > 프론트 메시지 > 기본 메시지 순으로 매핑
    const status = error.response?.status;
    const message =
      error.response?.data?.message ??
      (status ? RESPONSE_MESSAGE[status] : undefined) ??
      '알 수 없는 오류가 발생했습니다.';

    if (import.meta.env.DEV) {
      /* ... console.error(url, message) ... */
    }

    throw error;
  }
};



src/shared/api/response.ts

 

HTTP 상태 코드와 그에 따른 기본 메시지를 상수로 관리하여, 매직 넘버 사용을 줄이고 메시지를 통일했습니다.

export const HTTP_STATUS = {
  OK: 200,
  CREATED: 201,
  BAD_REQUEST: 400,
  // ... 
  SERVER_ERROR: 500,
} as const;

// 상태별 기본 메시지
export const RESPONSE_MESSAGE: Record<number, string> = {
  [HTTP_STATUS.OK]: '요청이 성공했습니다.',
  [HTTP_STATUS.BAD_REQUEST]: '입력값이 올바르지 않습니다.',
  // ...
};

 

 

3. Ky

kysms 경량 HTTP 클라이언트 라이브러리로, fetch와 ESM을 기반으로 동작하며 사용성을 개선한 것이 특징이다. 기본적으로 JSON 변환, 타임아웃 처리, 간결한 API 인터페이스를 제공하여 번거로운 설정 없이도 효율적인 네트워크 요청을 수행할 수 있다. ⇒ axios보다 훨씬 가볍다.
https://www.npmjs.com/package/ky

 

 

 

장점:

  • 가벼운 용량: Fetch를 래핑하여 만들었기 때문에 매우 가볍고 번들 크기에 부담이 적습니다.
  • 간결한 문법: Fetch보다 직관적인 API를 제공하며 체이닝 방식을 지원합니다.
  • 편의 기능 제공: 타임아웃, 재시도(Retry), 훅(Hooks) 등의 유용한 기능을 내장하고 있습니다.
  • TypeScript 지원: TypeScript를 완벽하게 지원하여 타입 안정성을 보장합니다.
  • 자동 JSON 파싱 및 에러 처리: Axios처럼 JSON 자동 파싱과 HTTP 에러 처리를 지원합니다.

단점:

  • 인지도 부족: Axios에 비해 상대적으로 인지도가 낮아 커뮤니티 지원이나 자료가 부족할 수 있습니다.
  • Node.js 설정 필요: 기본적으로 브라우저 환경에 최적화되어 있어 Node.js 환경에서는 추가 설정이 필요할 수 있습니다.

 

ky 사용법

ky를 설치하려면 다음 명령어를 실행해야한다.

npm install ky

 

ky는 요청 인터셉터, 재시도(retry) 기능, 헤더 설정 등을 지원하며, 필요에 따라 확장하여 사용할 수 있다.

 

 

아래는 코드 예시이다.

 

1) ky.create()

// src/shared/api/api-client.ts
import ky from 'ky';

export const api = ky.create({
  prefixUrl: import.meta.env.VITE_API_BASE_URL, 
  credentials: 'include', // 쿠키 포함 요청

  timeout: 10_000,        // fetch에는 없는 timeout 내장
  retry: { limit: 2 },    // fetch에는 없는 retry 내장

  hooks: {
    // Axios interceptor처럼 요청 직전 공통 처리 가능
    beforeRequest: [
      (request) => {
        const token = localStorage.getItem('token');
        if (token) request.headers.set('Authorization', `Bearer ${token}`);
      },
    ],

    // 응답 직후 공통 처리 가능 
    afterResponse: [
      (_request, _options, response) => {
        if (response.status === 401) window.location.href = '/login';
        return response;
      },
    ],
  },
});

 

 

 

2) GET/POST

// GET
type User = { id: number; name: string };

const users = await api.get('users', {
  searchParams: { page: 1, limit: 10 }, // => ?page=1&limit=10 자동
}).json<User[]>(); 

// POST
const created = await api.post('posts', {
  json: { title: 'foo', body: 'bar' }, // body + 헤더 처리 자동
}).json<{ id: number }>();

 

  • searchParams로 쿼리 스트링을 직접 조립하지 않아도 되고, json 옵션 하나로 JSON 전송을 자동 처리한다.
  • 응답은 .json<T>() 체이닝으로 바로 파싱하며, TypeScript 제네릭으로 타입까지 함께 가져갈 수 있다

 

 

3) HTTPError로 에러 처리

import { HTTPError } from 'ky';

try {
  await api.get('me').json();
} catch (e) {
 
  if (e instanceof HTTPError) {
    const status = e.response.status;

    // 서버가 에러 바디를 주면 읽어서 로깅 가능
    const payload = await e.response.clone().json().catch(() => null);

    console.error('HTTPError:', status, payload?.message);
  }
  throw e;
}

 

  • Ky는 기본적으로 4xx/5xx 응답을 HTTPError로 던져서(fetch의 res.ok 체크처럼) 수동 에러 분기 코드를 줄일 수 있다.
  • 에러 객체에서 response.status와 서버 에러 바디(JSON)를 읽어 공통 로깅/메시지 매핑을 쉽게 구성할 수 있다.

 

 

 

라이브러리 비교 

특징 Fetch Axios Ky
기반 브라우저 내장 API XMLHttpRequest (브라우저) / http (Node.js) Fetch API
설치 불필요 필요 (npm install axios) 필요 (npm install ky)
JSON 파싱 수동 (.json()) 자동 자동 (.json())
에러 처리 수동 (res.ok 확인) 자동 (HTTP 상태 코드 기반) 자동 (HTTP 상태 코드 기반)
인터셉터 없음 (직접 구현 필요) 지원 지원 (Hooks)
타임아웃/취소 직접 구현 필요 지원 지원
번들 크기 없음 (내장) 상대적으로 큼 작음
주요 사용 환경 간단한 프로젝트, 최신 브라우저 대규모 프로젝트, 구형 브라우저 지원 필요 현대적인 프로젝트, 경량화 중요

 

 

 

어떤 라이브러리를 선택해야 할까?

  • Fetch: 외부 라이브러리 설치 없이 가볍게 시작하고 싶거나, 최신 브라우저 환경만 지원하면 되는 경우. React Query나 SWR 같은 상태 관리 라이브러리와 함께 사용할 때.
  • Axios: 구형 브라우저 지원이 필수적이거나, 복잡한 요청 처리, 인터셉터 등 다양한 기능이 필요한 대규모 프로젝트의 경우.
  • Ky: Fetch의 가벼움과 Axios의 편의성을 동시에 원하며, 최신 브라우저 환경을 타겟으로 하는 경우.