Back

Axios

문득 이상한 생각이 들었다. 개발 환경이 nodeJS에 HTTP 요청이 필요하다면 무지성으로 Axios 패키지를 설치한다.
개발 환경이나, 빌드를 통해 실행하는 환경이 둘 다 웹 브라우저인 앱의 경우에도 그렇게 한다. 브라우저에서 XMLHttpRequest 객체를 이용한 AJAX나 Fetch API를 통해 충분히 HTTP request를 보낼 수 있는데, 왜 굳이 저런 것을 사용하지? 이미 내장되어있는 잘 만들어진 것을 사용하지 않고 굳이 용량까지 차지해가며 이런 것을 쓰는 이유는 뭐가 더 편리해서일까? 이런 생각이 들게 되었다.

나도 JSON 데이터 응답받는 API를 불러오는 통신을 Axios를 통해서 했었는데, 왜 썼는지조차 기억이 나지 않는다. 그냥 좋은 예제들이 다 이것들을 사용하고 있어서일까?

모르겠다. 애매하다. 이번 기회에 알아보도록 한다.


인터넷을 통해 많은 정보를 얻게 되었으며, 가장 진보되어있는 ES6표준으로 나온 Fetch API와 Axios의 차이점에 대해 알아보자.

호환성

Axios는 여러 종류의 브라우저에서 호환이 가능하다. 특히 죽어가는 브라우저 Internet Explorer 11에서도 사용이 가능하다. 반면 Fetch를 사용할 수 있는 브라우저는 다음과 같다.

Fetch를 사용할 수 있는 브라우저

근데 오로지 낮은 버젼의 브라우져에서 사용하기 위해 Axios를 사용한다면 그냥 polyfill을 쓰라고 한다. 그만큼 이외에 더 많은 장점이 존재한다는 뜻이니 더 알아보자.

timeout

Axios는 timeout을 설정하는 데 매우 간단하다.

axios({
  method: 'post',
  url: '/login',
  timeout: 4000, // 4 seconds timeout
  data: {
    firstName: 'David',
    lastName: 'Pollock',
  },
})
  .then((response) => {
    /* handle the response */
  })
  .catch((error) => console.error('timeout exceeded'));

axios configuration 객체 속에 timeout 프로퍼티 하나만 추가해주면 뚝딱 된다.

반면 Fetch는 이것을 사용하기 위해 AbortController라는 인터페이스를 통해 구현을 해야 한다고 한다. 구현하는 방법은 AbortController.AbortController() 생성자를 통해 AbortController 객체를 생성하고, 그리고 생성된 객체의 signal 프로퍼티를 통해 네트워크 호출함수인 fetch에다가… 아, 쉬운 거 먼저 알고 나니 알아보기 싫다. 이놈은 그만 알아보도록 하자.

자동 JSON 데이터 변환

Axios는 별도의 설정 없이 JSON 문자열로 변환해준다. 또한 오버라이딩을 통해 다른 형태로 변환이 가능하다고 한다.

Fetch는 직접 response.json()을 통해 변환 해야 한다.

// axios
axios.get('https://api.github.com/orgs/axios').then(
  (response) => {
    console.log(response.data);
  },
  (error) => {
    console.log(error);
  }
);

// fetch()
fetch('https://api.github.com/orgs/axios')
  .then((response) => response.json()) // one extra step
  .then((data) => {
    console.log(data);
  })
  .catch((error) => console.error(error));

HTTP interceptors

Axios는 HTTP requests를 가로챌 수 있는 기능이 존재한다. 애플리케이션에서 서버로 혹은 반대로 보낸 HTTP requests를 검사하거나, 변경하기가 쉽다.

axios.interceptors.request.use((config) => {
  // log a message before any HTTP request is sent
  console.log('Request was sent');

  return config;
});

// sent a GET request
axios.get('https://api.github.com/users/sideshowbarker').then((response) => {
  console.log(response.data);
});

Fetch의 경우에는 기본적으로 이런 기능을 제공하지 않아 직접 전역 fetch 메서드를 오버라이드 하여 가져와야 한다고 한다.

다운로드 진행률 표시

Axios는 Axios Progress Bar 라는 모듈을 통해 다운로드 진행률 표시를 쉽게 구현할 수 있다고 한다.

Axios를 사용하지 않으면 XMLHttpRequest.onprogress 의 콜백 핸들러를 통해 구현하거나, Fetch API의 경우 ReadableStream을 사용한다고 한다.

동시 요청

Axios는 동시에 요청을 보내기 위해 axios.all() 메서드를 사용한다.

이후 axios.spread() 메서드를 사용하여 여러 요청을 보낸 것들의 응답을 받아온다.

fetch의 경우 Promise.all()을 사용하여 같은 기능 구현이 가능하다.

어떤 의문의 고수가 이야기해 주는 장점

나 같은 경우 어차피 구글링을 통해 복붙을 하여 사용하고 막히면 또 검색해서 부분부분 수정하기 때문에, 또한 많은 경험이 없기 때문에 비교가 불가능하나, 어떤 고수는 경험을 통해 자기가 이렇게 느꼈다고 말한다.

XMLHttpRequest는 onload 때문에 구리다 하였고,

Fetch API는 에러 핸들링이 귀찮다고 하였다.


경험을 통해 알게된 장점

  • 원래 NodeJS 자체에서 http request를 하기 위해서 코드를 작성하려면, 브라우저 fetch가 존재하지 않아 예전에는 이를 무조건 사용해야했다고 한다. 그래서 기존에 사용했던 사람이 많으며, 문제해결에 도움이 될만한 여러 자료들이 많이 존재한다.
  • axios.defaults.baseURL 설정을 통해 기본 URL 변경이 내장된 설정을 통해 쉽게 가능하다. 이 라이브러리 없이 이것을 구현을 하려면, baseURL값이 존재하는 어떤 파일을 하나 만들고, 모든 http request하는 곳에서는 모듈 시스템을 통해 이 값을 받아야한다.
    보통 모든 곳에서 값을 받아서 요청할 url을 만드는 것이 귀찮아 이를 반복적으로 꺼내서 사용할 수 있도록 사용할 XMLHttpRequest라던가 , FetchApi를 사용하는 새로운 함수를 만들 것이다.
    그 함수는 어딘가에서 관리되는 baseURL을 받아 기본적으로 설정하고, 파라미터를 통해 뒤에 붙을 URL을 완성하는 형태가 될 것이다.
    위에 작성한 것 처럼 저렇게까지 관리하면, 어차피 axios를 사용하더라도 어차피 이를 사용하는 모든 곳에서 import 해야해서 조삼모사같지만, 위와같은 몇가지 설정 파일을 직접 만들 필요가 없다는 것은 장점인 것 같다.