Fetch API vs Axios

yeonjeong·2025년 2월 9일

앞서 살펴보았던 http에 대해서 알아볼 때 서버와 클라이언트 간의 데이터 통신을 할 때
클라이언트가 리퀘스트를 보내면 서버가 여러 단계를 거쳐서 서버가 응답을 해준다는 것을 살펴보았습니다.

API를 통해 리퀘스트를 보내는 경우, 여러분은 fetch와 axios 어떤 것을 사용하시나요?
오늘은 둘을 비교 분석해보는 시간을 가져보겠습니다.

Fetch vs axios

Fetch

  • 2015년부터 웹 브라우저에서 사용할 수 있는 내장 함수, 별도의 설치 없이 사용 가능
  • promise 기반으로 비동기 통신을 지원

axios

  • 2015년 첫 릴리즈된 HTTP 클라이언트 라이브러리
  • promise 기반의 비동기 통신을 지원
  • return을 promise 객체로 해주기 때문에 response 데이터를 다루기 쉬움
  • 외장 모듈이라 npm을 통한 설치가 필요

두 가지 HTTP Request에 대해서 간단하게 정리해보았는데,
실제 Request 코드를 보면서 차이점에 대해서 알아보도록 하겠습니다.

GET

: API 서버의 등록된 데이터를 뽑아보자 !

Fetch

async function getProduct(id) {
  try {
    const res = await fetch(
      `https://panda-market-api-crud.vercel.app/products/${id}`
    );

    if (!res.ok) {
      throw new Error(`HTTP error! ${res.status}`);
    }

    const data = await res.json();
    return data;
  } catch (error) {
    console.log("Error!");
  } finally {
    console.log("Finished!");
  }
}

1) fetch는 status가 404 에러나 다른 HTTP 에러 응답을 받았다고 해서 promise를 reject 하지 않기에 별도로 "if(!res.ok)"와 같이 에러를 처리할 수 있는 코드가 필요함
2) json 핸들링을 위해 데이터를 return시 별도 작업 필요
3) get method가 기본 지정이라 별도 옵션을 지정하지 않아도 됨

axios

import axios from "axios";

const instance = axios.create({
  baseURL: "https://panda-market-api-crud.vercel.app/",
  timeout: 5000,
});

function getArticle(id) {
  return instance
    .get(`/articles/${id}`)
    .then((res) => {
      return res.data;
    })
    .catch((e) => {
      if (e.response) {
        console.log(e.response.status);
        console.log(e.response.data);
      } else {
        console.log("ID 조회에 실패하였습니다.");
      }
    });
}

1) axios는 외장 모듈이기에 별도 설치 및 import 명령어 필요
2) 반복되는 URL은 instance 생성을 통해서 코드 단축 가능
3) 네트워크 응답 시간 Request timeout 설정 가능
4) get method가 기본값이라 옵션 설정하지 않아도 되지만, .get() 와 같이 별도의 함수를 제공하기에 명시적으로 사용
5) 가져온 데이터는 data 프로퍼티를 통해서 접근 가능(json 핸들링 내장)
6) 리퀘스트 실패 혹은 상태 코드가 실패(4XX, 5XX)를 나타내면 Promise가 reject 하기에 별도의 에러 코드 생략 가능

POST

: 데이터 생성하기

Fetch

async function createProduct(name, description, price, tags, images) {
  try {
    const res = await fetch(
      "https://panda-market-api-crud.vercel.app/products",
      {
        method: "POST",
        body: JSON.stringify({
          name: name,
          description: description,
          price: price,
          tags: tags || [],
          images: images || [],
        }),
        headers: {
          "Content-Type": "application/json",
        },
      }
    );

    if (!res.ok) {
      throw new Error(`HTTP error! ${res.status}`);
    }

    const data = await res.json();
    return data;
  } catch (error) {
    console.log("Error!");
  } finally {
    console.log("Finished!");
  }
}

1) body 옵션을 통해서 데이터 전송
- 데이터 타입 : applcation/json
- 문자 변환 : JSON.stringify

axios

function creatArticle(title, content, image) {
  return instance
    .post("/articles", {
      title,
      content,
      image,
    })
    .then((res) => {
      return res.data;
    })
    .catch((e) => {
      if (e.response) {
        console.log(e.response.status);
        console.log(e.response.data);
      } else {
        console.log("작성에 실패하였습니다.");
      }
    });
}

1) 데이터 전송을 data 옵션 사용
2) 자동으로 JSON 문자로 변환

PATCH

: 생성한 데이터 수정하기

Fetch

async function patchProduct(id, patchData) {
  try {
    const res = await fetch(
      `https://panda-market-api-crud.vercel.app/products/${id}`,
      {
        method: "PATCH",
        body: JSON.stringify(patchData),
        headers: {
          "Content-Type": "application/json",
        },
      }
    );

    if (!res.ok) {
      throw new Error(`HTTP error! ${res.status}`);
    }

    const data = await res.json();
    return data;
  } catch (error) {
    console.log("Error!");
  } finally {
    console.log("Finished!");
  }
}

axios

function patchArticle(id, data) {
  return instance
    .patch(`/articles/${id}`, data)
    .then((res) => {
      return res.data;
    })
    .catch((e) => {
      if (e.response) {
        console.log(e.response.status);
        console.log(e.response.data);
      } else {
        console.log("수정에 실패하였습니다.");
      }
    });
}

DELETE

: 생성 후 수정한 데이터 삭제하기!

Fetch

async function deleteProduct(id) {
  try {
    const res = await fetch(
      `https://panda-market-api-crud.vercel.app/products/${id}`,
      {
        method: "DELETE",
        headers: {
          "Content-Type": "application/json",
        },
      }
    );

    if (!res.ok) {
      throw new Error(`HTTP error! ${res.ststus}`);
    }

    const data = await res.json();
    return data;
  } catch (error) {
    console.log("Error!");
  } finally {
    console.log("Finished!");
  }
}

1) id로 삭제할 데이터를 찾으니, 추가 필요한 데이터가 없어서 body 생략

axios

function deleteArticle(id) {
  return instance
    .delete(`/articles/${id}`)
    .then((res) => {
      return res.data;
    })
    .catch((e) => {
      if (e.response) {
        console.log(e.response.satus);
        console.log(e.response.data);
      } else {
        console.log("삭제에 실패하였습니다.");
      }
    });
}

결론

axios

장점

  1. instance 생성을 통해 반복되는 코드 선언 및 객체 설정 가능
  2. 네트워크 응답 timeout을 통해서 응답 시간 지정 가능
  3. data 프로퍼티를 통해서 별도의 json 문자 변환 요청 없이 변환 가능
  4. .get()/.post()/.patch()/.delete() 함수 제공
  5. 네트워크 응답 실패 시(4xx, 5xx) reject (오류 코드 작성 필요 X)
  6. 다양한 프로퍼티 제공을 통해 간결한 코드 작성 가능

단점

  1. 외장 모듈이라 npm을 통한 설치 필요

fetch

장점

  1. 내장 모듈이라 바로 사용 가능
  2. 내용을 다 표시할 수 있어서 정보가 잘 표기되어있음

단점

  1. 네트워크 응답 실패 시 reject가 안되어 오류 코드 넣어야 함
  2. 문자 변환을 위해 json 핸들링 코드 작성 필요
  3. 내용을 다 명시해야해서 코드가 길어짐

출처
https://www.heropy.dev/p/QOWqjV
https://tlsdnjs12.tistory.com/26
https://velog.io/@eunbinn/Axios-vs-Fetch

profile
Backend 개발자로 거듭나는 그 날까지 !

0개의 댓글