그럼에도 불구하고

👨‍💻

[JavaScript] Fetch와 Axios의 차이점 비교 본문

JavaScript/JavaScript basics

[JavaScript] Fetch와 Axios의 차이점 비교

zenghyun 2023. 9. 5. 18:14



크고 작은 프로젝트를 진행하다 보면, 우리는 백엔드 또는 서드파티 API에 네트워크 요청(HTTP Requests)이 필요한 애플리케이션을 개발할 때 Fetch 혹은 Axios와 같은 HTTP 클라이언트를 사용합니다. 

 

이 글에서는 Fetch와 Axios에 대한 간단한 설명과 차이점에 대해 알아보겠습니다. 

 

 

🧑🏻‍💻 Fetch

Fetch API는 네트워크 요청을 위해 fetch()라는 메서드를 제공하는 인터페이스입니다. 모던 브라우저 자체에 내장되어 있어 따로 설치할 필요가 없으며, promise 기반의 HTTP 클라이언트로 resolve 혹은 reject 할 수 있는 promise가 반환됩니다. 

 

 

📌 문법

Fetch는 두 개의 인자를 받습니다. 첫 번째 인자는 내가 필요로 하는 리소스의 URL이며, 두 번째 인자는 요청의 설정 옵션을 포함하는 객체로 선택적 인자입니다. 

 

두 번째 인자로 옵션을 넣지 않을 경우, 기본적으로 GET 요청을 생성합니다. 

 

⭐️ 설정 옵션 X

fetch(url);

 

⭐️ 설정 옵션 O  ( 옵션이 있을 경우 다음과 같이 요청에 대해 커스텀 설정을 할 수 있습니다. )

fetch(url, {
	method: "GET", // (POST, PUT, DELETE, etc...)
    headers: {
    	"Content-Type": "application/json",
       },
       body: JSON.stringify({}),
});

 

 

📌 JSON 데이터 처리 ( GET )

⭐️ JSONPlaceholder REST API 사용 예시 

const url = "https://jsonplaceholder.typicode.com/todos";

fetch(url)
	.then((response) => response.json())
   	.then(console.log());

 

아래는 콘솔창에 출력된 결과입니다.

 

 

fetch 메서드는 .then() 메서드에서 처리된 promise를 반환합니다. fetch 메서드는 데이터의 포맷을 직접 지정해줘야 하기 때문에 응답 객체의. json() 메서드를 호출합니다. 그러면 JSON 형식의 데이터로 resolve 된 promise를 반환합니다. 

 

 

📌 JSON 데이터 처리 ( POST )

이번에는 반대로 JSONPlaceholder API를 사용하여 데이터를 전송해보겠습니다.

 

Fetch에는 데이터가 자동으로 JSON 문자열로 직렬화되지 않기 때문에  JSON.stringify()를 사용하여 객체를 문자열로 변환한 뒤 body에 할당해야 합니다. 

 

const url = "https://jsonplaceholder.typicode.com/todos";

const todo = {
	title : "A new todo",
    completed : false,
}; 

fetch(url, {
	method: "post",
    headers: {
    	"Content-Type": "application/json",
       },
    body: JSON.stringify(todo),
})
  .then((response) => response.json())
  .then((data) => console.log(data));

 

📌 에러 처리 

Fetch는 resolve 되거나 reject 된 promise를 반환한다고 했습니다. 여기서 promise가 reject 되면,. catch()를 사용하여 에러를 처리할 수 있습니다.

 

Fetch의 경우 네트워크 장애가 발생한 경우에만 promise를 reject 합니다. 만약 404 에러나 HTTP 에러가 발생한 경우에는 응답하지 않기 때문에 .then절을 사용하여 수동으로 직접 처리해줘야 합니다. 

 

const url = "https://jsonplaceholder.typicode.com/todos"; 

fetch(url)
	.then((response) => {
    	if(!response.ok) {
        	throw new Error(`This is an HTTP error: The status is ${response.status}`);
            }
       	return response.json();
       })
       .then(console.log())
       .catch((err) => {
       	console.log(err.message);
      });

만약 응답 블록에서 응답의 ok 상태가 false인 경우 .catch 블록에서 처리되는 커스텀 에러를 발생시킵니다.

 

위 사진은 fetch가 성공했을 때의 사진으로, 만약 잘못된 URL 엔드포인트를 요청했을 경우 ok와 status의 속성은 각각 false와 404 값을 가지게 됩니다. 이에 에러를 발생시키고 .catch() 절에서 커스텀 에러 메시지를 출력합니다.

 

📌 응답 시간 초과 / 요청 취소

Fetch 통한 요청을 취소할 때는 AbortController 인터페이스를 사용하면 됩니다.

const url = "https://jsonplaceholder.typicode.com/todos";

const controller = new AbortController();
const signal = controller.signal;

setTimeout(() => controller.abort(), 4000); 

fetch(url, {
	signal: signal, 
})
  .then((response) => response.json())
  .then(console.log())
  .catch((err) => {
  	console.error(err.message);
  });

 

우선, controller 객체를 생성하고 나서 signal 객체와 abort() 메서드에 접근합니다. 이 signal 객체를 설정 옵션을 통해 fetch()에 넘깁니다. 이렇게 하면 abort 메서드가 호출될 때마다 fetch 요청이 종료되며, setTimeout 기능을 사용하여 서버가 4초 이내로 응답하지 않으면 작업이 종료됩니다.

 

🧑🏻‍💻 Axios

Axios는 서드파티 라이브러리로 CDN 혹은 npm이나 yarn과 같은 패키지 매니저를 통해 설치하여 프로젝트에 추가할 수 있습니다.

또한 Axios는 브라우저 혹은 node.js 환경에서 실행할 수 있습니다.

 

Axios는 Fetch와 마찬가지로 promise 기반의 HTTP 클라이언트이며, resolve 혹은 reject 할 수 있는 promise가 반환됩니다. 

 

 

📌 install

// npm ver
npm install axios 

// yarn ver
yarn add axios

 

설치 후에는 사용할 프로젝트에서 import 하면 됩니다. :) 

import axios from "axios";

 

📌 문법

Axios 문법은 Fetch와 비슷하나, 다양한 방법으로 요청할 수 있고, 생략할 수 있는 구문이 있습니다.

 

axios(url, {
	// 설정 옵션
});

아래와 같이 HTTP 메서드를 붙여서 사용할 수 있습니다. 

axios.get(url, {
	// 설정 옵션
});

또한, fetch 메서드처럼 HTTP 메서드 없이 요청할 경우 기본적으로 GET 요청을 생성합니다. 

axios(url);

그리고 Fetch와 마찬가지로 두 번째 인자를 사용하여 커스텀 설정하는 것도 가능합니다.

axios(url, {
	method: "get", // (post, put, delete, etc...)
    headers: {},
    data: {},
});

아래처럼 작성하는 것도 가능합니다.

axios({
	method: "get",
   	url: url,
    headers: {},
    data: {},
});

이제 Axios와 Fetch의 응답 처리 시 어떤 차이가 있는지 자세히 알아보겠습니다.

 

📌 JSON 데이터 처리 ( GET )

⭐️ Fetch ver

const url = "https://jsonplaceholder.typicode.com/todos";

fetch(url)
	.then((response) => response.json())
   	.then(console.log());

아래는 위의 요청을 Axios로 수행하는 코드입니다.

 

⭐️ Axios ver

const url = "https://jsonplaceholder.typicode.com/todos";

axios.get(url).then((response) => console.log(response.data));

Fetch 메서드와 다르게 Axios를 사용하면 응답 데이터를 기본적으로 JSON 타입으로 사용할 수 있습니다.

 

혹은 아래와 같이 설정 옵션을 통해 responseType을 지정하여 기본 JSON 데이터 타입을 재정의 할 수도 있습니다. 

 

axios.get(url, {
	responseType: "json", // options: "arraybuffer", "document", "blob", "text", "stream" 
});

 

📌 JSON 데이터 처리 ( POST )

const url = "https://jsonplaceholder.typicode.com/todos"; 

const todo = {
	title: "A new todo",
    completed: false,
};

axios.post(url, {
	headers: {
    	"Content-Type": "application/json",
       },
       data: todo,
      })
      .then(console.log());

 

Axios로 post 요청을 할 때 request body으로 보내고자 하는 data는 data 프로퍼티에 할당합니다. 콘텐츠 유형 헤더도 설정할 수 있으며, 기본적으로 axios는 Content-Type을 application/json으로 설정하며 생략 가능합니다.

(Fetch는 명시적으로 "Content-Type": "application/json"을 작성해야 함)

 

Fetch 메서드와 다른 점은 JSON.stringify()를 사용하여 객체를 문자열로 변환할 필요가 없어 보다 간편하게 사용할 수 있습니다. 

 

📌 에러 처리 

Axios는 Fetch에 비해 에러를 처리하는 방법이 보다 간결합니다.

 

const url = "https://jsonplaceholder.typicode.com/todos"; 

axios.get(url)
	 .then((response) => console.log(response.data))
     .catch((err) => {
     	console.log(err.message);
     });

Axios의 경우 promise의 상태코드가 200 ~ 299를 넘어가면 reject 시킵니다.

또한, 에러 객체에 response 또는 request 프로퍼티가 포함되어 있는지 확인하여 에러에 대한 자세한 정보를 확인할 수 있습니다.

.catch((err) => {
// 에러 처리
if(err.message) {
// 요청이 이루어지고 서버가 응답 
	const { status, config } = err.response; 
    
    if(status === 404) {
    	console.log(`${config.url} not found`);
       }
    if(status === 500) {
    	console.log("Server error");
       } 
} else if (err.request) {
	// 요청이 이루어졌으나 서버에서 응답하지 않을 경우 
    console.log("Error", err.message);
   } else {
   	// 그 외 다른 처리 
    console.log("Error", err.message);
    }
  });

에러 객체의 response 프로퍼티는 클라이언트가 2xx 범위를 벗어나는 상태 코드를 가진 에러 응답을 받았음을 나타냅니다.

에러 객체의 request 프로퍼티는 요청이 수행되었지만 클라이언트가 응답을 받지 못했음을 나타냅니다. 

 

요청 또는 응답 속성이 모두 없는 경우는 네트워크 요청을 설정하는 동안 오류가 발생한 경우를 나타냅니다. 

 

📌 응답 시간 초과 / 요청 취소

Axios에서는 timeout 속성을 설정 객체에 추가하여 요청이 종료될 때까지의 시간을 밀리초로 지정할 수 있습니다.

 

const url = "https://jsonplaceholder.typicode.com/todos"; 

axios.get(url, {
	timeout: 4000, // default 0
    })
    .then((response) => console.log(response.data))
    .catch((err) => {
    	console.log(err.message);
    });

 

🧑🏻‍💻 요약

📌 공통점

 

Fetch와 Axios 모두 백엔드 또는 서드파티 API에 네트워크 요청이 필요할 때 사용하며 promise 기반으로 resolve와 reject 할 수 있는 promise를 반환합니다. 

 

📌 차이점

Fetch Axios
별도의 설치 없이 사용할 수 있습니다.  써드파티 패키지로 따로 설치해야 합니다.
JSON 핸들링을 위한 추가 절차가 필요합니다. ( json() ) 자동으로 JSON 데이터 변환을 지원합니다.
요청시간에 관한 별도의 기능이 없습니다. 
( AbortController 이용하여 구현 가능 )
요청시간에 관하여 Request 취소와 Request Timeout을 설정할 수 있습니다.
resonse를 얻을 때 response 객체의 json 메서드를 호출하여 body에 접근하여 json 객체를 얻습니다.  response를 얻을 때 response 객체의 data property에 접근하여 얻습니다.
업데이트가 빠른 React-native에 사용하기 좋습니다. 업데이트가 다소 느린 React에서 사용하기 좋습니다. 

 

🏷️ 출처

https://velog.io/@eunbinn/Axios-vs-Fetch

https://velog.io/@sunkim/React-axios-%EC%99%80-fetch-%EC%B0%A8%EC%9D%B4%EC%A0%90

 

 

Comments