Axios가 뭔데

임철종·2023년 2월 27일
0
post-thumbnail

Axios?

Axios는 node.js와 브라우저의 통신을 위한 Promise 기반 HTTP 클라이언트 이다.

서버 사이드에서는 native node.js의 http모듈을 사용하고 클라이언트(브라우저)에서는 XMLHttpRequests를 사용한다.

특징

  • 브라우저를 위해 XMLHttpRequests 생성
  • node.js를 위해 http 요청 생성
  • Promise API를 지원
  • 요청 및 응답 인터셉트
  • 요청 및 응답 데이터 변환
  • 요청 취소
  • JSON 데이터 자동 병환
  • XSRF를 막기위한 클라이언트 사이드 지원

Axios API

GET 요청

const axios = require('axios');

// 지정된 ID를 가진 유저에 대한 요청
axios.get('/user?id=123')
	.then((response) => {
    	// 성공 핸들링
    	console.log(response)
    })
    .catch((error) => {
    	// 에러 핸들링
    console.log(error)
    })
    .finally(() => {
    	// 항상 실행되는 영역 (실패든 성공이든)
    })

또는 다음과 같이 실행 할 수 있다.

axios.get('/user', {
    params: {
      id: 123
    }
  })
  // 생략

async/await 를 사용하려면 외부 함수를 async로 선언해야 한다.

async function getUser() {
  try {
    const response = await axios.get('/user?id=12345');
    console.log(response);
  } catch (error) {
    console.error(error);
  }
}

POST 요청

POST 요청 생성 (JSON)

// 유저를 등록하는 요청
axios.post('/user', {
    firstName: 'Sam',
    lastName: 'Smith'
  })
  .then((response) => {
    console.log(response);
  })
  .catch((error) => {
    console.log(error);
  });

동시에 여러 요청 생성

function getUserAccount() {
  return axios.get('/user/123');
}

function getUserPermissions() {
  return axios.get('/user/123/permissions');
}

Promise.all([getUserAccount(), getUserPermissions()])
  .then((results) => {
    const acct = results[0];
    const perm = results[1];
  });

HTML form을 JSON으로 POST 요청

const {data} = await axios.post('/user', document.querySelector('#my-form'), {
  headers: {
    'Content-Type': 'application/json'
  }
})

Forms

  • Multipart(multipart/form-data)
    const {data} = await axios.post('https://somewhere.org/post', {
       firstName: 'Sam',
       lastName: 'Smith',
       orders: [1, 2, 3],
       photo: document.querySelector('#fileInput').files
     }, {
       headers: {
         'Content-Type': 'multipart/form-data'
       }
     }
    )
  • URL encoded form(application/x-www-form-urlencoded)
     const {data} = await axios.post('https://somewhere.org/post', {
        firstName: 'Sam',
        lastName: 'Smith',
        orders: [1, 2, 3],
        photo: document.querySelector('#fileInput').files
      }, {
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        }
      }
    )

Config

요청의 마지막 인자로 config 객체를 전달하여 관련 설정을 보낼 수 있다.
axios(config)

// POST 요청
axios({
  method: 'post',
  url: '/user/123',
  data: {
    firstName: 'Sam',
    lastName: 'Smith'
  }
});
// node.js에서 원격 이미지를 요청하는 GET 요청
axios({
  method: 'get',
  url: 'http://bit.ly/2mTM3nY',
  responseType: 'stream'
})
  .then(function (response) {
    response.data.pipe(fs.createWriteStream('some_image.jpg'))
  });

The Axios Instance

사용자 지정 config로 새 axios 인스턴스를 만들 수 있다.
axios.create([config])

const instance = axios.create({
  baseURL: 'https://some-domain.com/api/',
  timeout: 1000,
  headers: {'X-Custom-Header': 'foobar'}
});

Response Schema

request에 대한 response는 아래의 정보를 가지고 있다.

{
  // 서버가 제공하는 응답
  data: {},

  // HTTP 상태 코드
  status: 200,

  // HTTP 상태 메시지
  statusText: 'OK',

  // HTTP 헤더
  // 모든 헤더 이름은 소문자이며, 괄호 표기법을 사용하여 접근할 수 있다.
  // 예시: `response.headers['content-type']`
  headers: {},

  // 요청을 위해 `Axios`가 제공하는 구성
  config: {},

  // 이번 응답으로 생성된 요청
  // node.js에서는 마지막 ClientRequest 인스턴스
  // 브라우저에서는 XMLHttpRequest
  request: {}
}

then을 사용하면 아래와 같은 response를 받는다.

axios.get('/user/123')
  .then(function (response) {
    console.log(response.data);
    console.log(response.status);
    console.log(response.statusText);
    console.log(response.headers);
    console.log(response.config);
  });

catch를 사용하거나, 거부 콜백 함수를 then의 두번째 인자로 넘길 시, 에러 핸들링에서 설명된 error 객체를 사용할 수 있다.

Config 기본값

전역 axios 기본값

axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

커스텀 instance 기본값

// 인스턴스를 생성할때 config 기본값 설정하기
const instance = axios.create({
  baseURL: 'https://base_url.com'
});

// 인스턴스를 만든 후 기본값 변경하기
instance.defaults.headers.common['Authorization'] = AUTH_TOKEN;

Config 우선 순위
config는 우선 순위에 따라 병합된다.
lib/defaults.js 라이브러리에서 기본값, 인스턴스의 defaults 속성, 요청의 config 인자를 순서대로 찾는다.

Interceptors

then 또는 catch로 처리되기 전에 요청과 응답을 가로챌 수 있다.

// 요청 인터셉터 추가하기
axios.interceptors.request.use((config) => {
    // 요청이 전달되기 전에 작업 수행
    return config;
  }, (error) => {
    // 요청 오류가 있는 작업 수행
    return Promise.reject(error);
  });

// 응답 인터셉터 추가하기
axios.interceptors.response.use((response) => {
    // 2xx 범위에 있는 상태 코드는 이 함수를 트리거
    // 응답 데이터가 있는 작업 수행
    return response;
  }, (error) => {
    // 2xx 외의 범위에 있는 상태 코드는 이 함수를 트리거
    // 응답 오류가 있는 작업 수행
    return Promise.reject(error);
  });

필요할 때 interceptor를 제거할 수 있다.

const myInterceptor = axios.interceptors.request.use(() => {/*...*/});
axios.interceptors.request.eject(myInterceptor);

커스텀 인스턴스에서도 interceptor를 추가할 수 있다.

const instance = axios.create();
instance.interceptors.request.use(() => {/*...*/});

Error Handling

axios.get('/user/12345')
  .catch((error) => {
    if (error.response) {
      // 요청이 전송되었고, 서버는 2xx 외의 상태 코드로 응답
      console.log(error.response.data);
      console.log(error.response.status);
      console.log(error.response.headers);
    } else if (error.request) {
      // 요청이 전송되었지만, 응답이 수신되지 않음
      // 'error.request'는 브라우저에서 XMLHtpRequest 인스턴스이고,
      // node.js에서는 http.ClientRequest 인스턴스이다.
      console.log(error.request);
    } else {
      // 오류가 발생한 요청을 설정하는 동안 문제가 발생
      console.log('Error', error.message);
    }
    console.log(error.config);
  });

config 옵션 중 validateStatus를 사용하면, 오류를 발생시키는 HTTP 상태 코드를 정의할 수 있다.

axios.get('/user/123', {
  validateStatus: (status) => {
    return status < 500; // 상태 코드가 500 미만인 경우에만 해결
  }
})

toJSON을 사용하면 HTTP 에러에 대한 더 많은 정보를 객체 형식으로 가져온다.

axios.get('/user/123')
  .catch((error) => {
    console.log(error.toJSON());
  });

요청 취소

취소 토큰을 이용하여 요청을 취소할 수 있다.
아래와 같이 CancelToken.source 팩토리를 사용하여 취소 토큰을 만들 수 있다.

const CancelToken = axios.CancelToken;
const source = CancelToken.source();

axios.get('/user/123', {
  cancelToken: source.token
}).catch((thrown) => {
  if (axios.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
    // 에러 핸들링
  }
});

axios.post('/user/123', {
  name: 'new name'
}, {
  cancelToken: source.token
})

// 요청 취소하기 (메시지 파라미터는 옵션)
source.cancel('Operation canceled by the user.');

실행자 함수를 CancelToken 생성자에 전달하여, 취소 토큰을 만들 수 있다.

const CancelToken = axios.CancelToken;
let cancel;

axios.get('/user/12345', {
  cancelToken: new CancelToken((c) => {
    // 실행자 함수는 취소 함수를 파라미터로 받습니다.
    cancel = c;
  })
});

// 요청 취소하기
cancel();

URL-Encoding Bodies

보통 axios는 JSON을 사용한다. application/x-www-form-urlencoded 포맷으로 데이터를 전송하려면 다음 옵션 중 하나를 사용할 수 있다.

브라우저
브라우저에서는 URLSearchParams API를 사용할 수 있다.

const params = new URLSearchParams();
params.append('param1', 'value1');
params.append('param2', 'value2');
axios.post('/foo', params);

Node.js
querystring 모듈

const querystring = require('querystring');
axios.post('http://something.com/', querystring.stringify({ foo: 'bar' }));

url moduleURLSearchParams

const url = require('url');
const params = new url.URLSearchParams({ foo: 'bar' });
axios.post('http://something.com/', params.toString());

qs 라이브러리


Form data
node.js에서 다음과 같이 form-data 라이브러리를 사용할 수 있다.

const FormData = require('form-data');
 
const form = new FormData();
form.append('my_field', 'my value');
form.append('my_buffer', new Buffer(10));
form.append('my_file', fs.createReadStream('/foo/bar.jpg'));

axios.post('https://example.com', form, { headers: form.getHeaders() })

interceptor를 사용할수도 있다.

axios.interceptors.request.use(config => {
  if (config.data instanceof FormData) {
    Object.assign(config.headers, config.data.getHeaders());
  }
  return config;
});

마침

회사에서 진행한 프로젝트에서 axios를 사용하게 되어 axios 공식 홈페이지의 docs를 보며 정리한 내용이다.
사용법도 어렵지 않고 커스텀 인스턴스를 만들 수 있는 점이나 인터셉터를 활용한 로그인 여부 처리, 에러 페이지 보여주기 등 유용한 라이브러리였다.

profile
🌑🌘🌗🌖🌕

0개의 댓글