✔️Axios 와 Fetch

Wiiiiiii·2022년 12월 16일
0

Reactstudy

목록 보기
5/5
post-thumbnail

원문 : https://meticulous.ai/blog/fetch-vs-axios/

백엔드 또는 서드파티 API에 네트워크 요청이 필요한 어플리케이션을 개발할 때 Axios 및 Fetch와 같은 HTTP 클라이언트를 사용한다

Fetch 및 Axios 에 대한 간략한 개요

Fetch API 는 네트워크 요청을 위해 fetch() 라는 매서드를 제공하는 인터페이스이다
모던 브라우저에 내장되어 있어 따로 설치할 필요가 없다

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

Fetch와 Axios는 모두 Promise 기반의 HTTP 클라이언트이다 즉, 이 클라이언트를 이용해 네트워크 요청을 하면 이행 (resolve) 혹은 거부 (reject) 할 수 있는 promise 가 반환된다

Syntax

Fetch는 두 개의 인자를 받는다. 첫 번째 인자는 가져오고자 하는 리소스의 URL이다
두 번째 인자로는 요청의 설정 옵션을 포함하는 객체로 선택적 인자이다

두 번째 인자로 설정 옵션을 넘기지 않을 경우 기본적으로 GET 요청을 생성한다

fetch(URL);

설정 옵션을 넘기면 다음과 같이 요청에 대해 커스텀 설정을 할 수 있다

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

Axios 의 문법도 비슷하나, 다양한 방법으로 요청할 수 있다

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

아래와 같이 HTTP 메서드를 붙일 수도 있다

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

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

axios(URL);

또, 두 번째 인자를 사용해서 커스텀 설정이 가능하다

axios(URL, {
	method: "get", // Can use otehr method (POST, PUT, DELETE etc..)
    headers: {},
    data: {},
});

아래처럼 작성할 수도 있다

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

JSON DATA Processing

아래 예제에서는 JSONPlaceholder라는 REST API에 GET 요청을 통해 URL의 아이템을 가져오며 fetch와 Axios의 차이점을 알아본다

Fetch API를 사용하면 코드는 다음과 같다

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

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

콘솔창에 출력된 결과는 다음과 같다

fetch().then() 메서드에서 처리된 Promise를 반환한다
이 때는 아직 우리가 필요한 JSON 데이터의 포맷이 아니기 때문에 응답 객체의 .json() 메서드를 호출한다

그러면 JSON 형식의 데이터로 이행(resolve)된 또 다른 promise를 반환한다
따라서 일반적인 fetch 요청은 두 개의 .then() 호출을 갖는다

다음은 같은 요청을 Axios로 수행하는 코드이다

const url = "https://jsonplaceholer.typicode.com/todos";
axios.get(url).then((response) => console.log(response.data));

Axios를 사용하면 응답 데이터를 기본적으로 JSON 타입으로 사용할 수 있다
응답 데이터는 언제나 응답 객체의 data 프로퍼티에서 사용할 수 있다

자동 문자열 반환 (Stringify)

JSONPlaceholder API를 사용해 데이터를 전송해보겠다

이를 위해서는 데이터를 JSON 문자열로 직렬화 해야 한다. POST 메서드로 JavaScript 객체를 API로 전송하면 Axios가 자동으로 데이터를 문자열로 변환해준다

Axios를 사용해 post 요청을 수행하는 코드를 살펴보자

const url = "https://jsonplaceholer.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-typeapplication/json 으로 설정한다

응답 객체를 살펴보도록 하자

응답 데이터는 다음과 같이 response.data 에 있다

.then(response => console.log(response.data));

Fetch API를 사용한다면 JSON.stringify() 를 사용하여 객체를 문자열로 변환한 뒤 body에 할당해야 한다

const url = "https://jsonplaceholer.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를 사용하면 명시적으로 Content-Typeapplication/json 으로 설정해주어야 한다

에러처리

Fetch와 Axios는 모두 이행(resolve) 되거나 거부(reject)된 promise를 반환한다
Promise가 거부(reject) 되면 .catch()를 사용하여 에러를 처리할 수 있다
Axios로 에러를 처리하는 방법은 Fetch에 비해 더 간결하다

Axios 부터 살펴보면 .catch()를 사용한 일반적인 에러 처리는 다음과 같다

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

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

Axios의 promise는 상태코드가 2xx 의 범위를 넘어가면 거부(reject)한다
에러 객체에 응답(response) 또는 요청(request) 프로퍼티가 포함되어 있는지 확인하여 에러에 대한 자세한 정보를 확인할 수 있다

.catch((err) => {
// 에러 처리
if (err.response) {
// 요청이 이루어졌고 서버가 응답했을 경우

    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);
  }
});

Fetch는 404에러나 다른 HTTP 에러 응답을 받았다고 해서 promise를 거부(reject)하지 않는다
Fetch는 네트워크 장애가 발생한 경우에만 promise를 거부(reject)한다
따라서 .then절을 사용해 수동으로 HTTP 에러를 처리해야 한다

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 블록에서 처리되는 커스텀 에러를 발생시킨다

다음과 같이 응답 객체에서 사용할 수 있는 메서드를 살펴볼 수 있다

.then(console.log)

응답 시간 초과 / 요청 취소

각각의 HTTP 클라이언트에서 HTTP 요청이 시간 초과될 경우 어떻게 처리하는 지 살펴보자

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

요청이 4초 이상 걸릴 경우 종료하고 console 창에 error를 로깅하는 코드이다

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

axios
  .get(url, {
    timeout: 4000, // 기본 설정은 '0'입니다 (타임아웃 없음)
  })
  .then((response) => console.log(response.data))
  .catch((err) => {
    console.log(err.message);
  });

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초 이내에 응답하지 않으면 작업이 종료된다

profile
리액트를 주로 연구중입니다! FE Junior

0개의 댓글