Axios 둘러보기

Rosevillage·2023년 4월 30일

무심코 써왔던 axios를 조금 더 효율적으로 사용해보기 위해 axios가 무엇이고 어떤 사용법이 있는지 정리해 본다.

Axios

동형(브라우저와 node.js에서 실행할 수 있는 동일한 코드데이스)의 Promise기반 HTTP 클라이언트 라이브러리로 서버 사이드에서는 node.js의 모듈을 사용하고, 브라우저에서는 XMLHttpRequests를 사용한다.

특징

기본적으로 사용되는 fetch와 비교했을때 크게 다음과 같은 특징을 지닌다.

  • 요청 메소드 명령어 제공

    • get(url[, config])
    • delete(url[, config])
    • head(url[, config])
    • options(url[, config])
    • post(url[, config])
    • put(url[, config])
    • patch(url[, config])
  • interceptors 제공
    리덕스의 미들웨어와 비슷하게 사용가능하며, then이나 catch로 처리되기 전에 요청이나 응답을 가로챌 수 있다.

    // 요청 인터셉터
    axios.interceptors.request.use(
     function(config) {
       // 요청전 수행 
       // ex) config.headers.common["Authorization"] = access_token;
       return config // 요청 헤더에 access token 추가
     },
     function(error) {
       // 오류 요청 전 수행
       return Promise.reject(error);
     }
    )
    // 응답 인터셉터
    axios.interceptors.response.use(
     function(response) {
       // 응답 데이터 가공
       // ex) setCookie("access_token", response.headers["authorization"])
       return response;
     },
     function(error) {
       // 오류 응답 처리
       return Promise.reject(error);
     }
    )
  • 커스텀 인스턴스
    사용자 지정 config로 새로운 axios 인스턴스를 생성할 수 있다.

    const instance = axios.create({
      baseURL: 'https://foo_and_bar-site.com/',
      headers: {
        "content-type": "application/json",
        accept: "application/json"
      }
    });
    
    instance.get('./user') 
    // instance를 통해 요청을 보낼때 작성한 config는 instance생성시 지정한 config와 결합된다.

알고 있어야 할 규칙

특징만 가지고는 axios를 잘 활용하기는 부족하기때문에 axios에서 소개하는 몇 가지 규칙을 통해 어떻게 사용해야 하는지 정리한다.

config 설정과 규칙

axios의 config는 개별설정과 기본설정 크게 두가지 방법을 지닌다.

  • 개별 설정: 말 그대로 axios로 요청을 보낼때 마다 config를 직접 작성하는 방식으로 각각의 요청 마다 다른 config를 가진다.

    axios.get('https://어쩌구.com', {
      headers: {
        "content-type": "application/json",
        // ...
      }
    })
  • 전역 설정: defualts 속성을 통해 모든 요청에 적용되는 config를 설정한다.

    axios.defauls.baseURL = 'https://어쩌구.com';
     axios.defauls.headers.common["Authorization"] = access_token;
     axios.defauls.withCredentials = true;
    
    // instance 도 defaults 속을 사용할 수 있다.
    instance.defaults.baseURL = 'https://저쩌구.com'

각 config들은 우선 순위에 따라 병합되는데 우선순위는 요청의 config 인자(개별 설정) > defaults 속성 > 라이브러리 기본값 순으로 후자로 갈수록 낮아진다.

때문에 defaults로 설정한 값과 다른 config 값이 필요하다면, 요청에 개별 config 값을 덮어 씌워서 사용할 수 있다.

오류 처리

axios는 기본적으로 2xx 범위를 벗어나는 staus는 오류로 처리한다. 공식문서에서 안내하는 오류처리에 대한 대략적인 구조는 다음과 같다

axios.get('https://어쩌구.com/user/1')
  .catch(function(err) {
    if(err.reponse) {
      // 요청이 전송되었지만 응답의 status가 2xx 초과 범위 
      console.log(err.response.data);
      console.log(err.response.status);
      console.log(err.response.headers);
    } else if(err.request) {
      // 요청이 전송되었지만 응답 없음
      console.log(err.request)
    } else {
      // 오류가 발생한 요청을 설정하는 동안 문제 발생
      console.log('Error', err.message)
    }
  })

validateStatus 를 통해 오류를 발생시키는 http 코드를 정의할 수도 있다.

axios.get('https://어쩌구.com/user/1', {
  validateStatus: function(status) {
    return status < 500; // status가 500 미만인 경우에만 resolve
  }
})

toJSON 을 통해 에러에 대한 더 많은 정보를 객체 형태로 가져올 수 있다.

axios.get('https://어쩌구.com/user/1')
  .catch(function (err) {
    console.log(err.toJSON());
  });

요청 취소

axios에서도 요청 취소를 위해 AbortController를 지원하는데 이를 통해 요청을 취소 시킬 수 있다.

  • AbortController : DOM 인터페이스 중 하나로 하나 이상의 웹 요청을 중단시킬 수 있는 컨트롤러 객체
  • AbortSignal: DOM 요청(fetch)과 통신하고 필요한 경우 AbortController를 통해 취소할 수 있게 해주는 신호 객체
  • AbortController.signal : AbortSignal객체 인터페이스를 반환
  • AbortController.abort() : signal이 포함된 DOM 요청이 완료되기 전에 취소
const controller = new AbortController(); // AbortController 인스턴스 생성

axios.get('https://어쩌구.com', {
   signal: controller.signal // axios option으로 취소 시그널 설정
}).then(function(response) {
   //...
});
// 요청 취소
controller.abort()

일부 포스팅들에서 axios가 AbortController를 지원하지 않고, 요청을 취소 하려면 CancelToken을 사용해야 한다고 말하고 있어 조금 혼란이 있었지만

axios github에서는 v0.22.0 부터 AbortController를 지원하고 있다고 안내하고 있으며, CancelToken은 deprecated 되었기 때문에 사용하지 않을 것을 권장하고 있다.
그러므로 요청 취소는 AbortController를 통해 구현해야 한다.


Reference

axios-시작하기

axios-github-Readme

0개의 댓글