Axios

2023-04-05
ꞏ
유영진
ꞏ
show5116
Axios

Axios란?

Axios는 비동기 통신 라이브러리로, 흔히 알고 있는 ajax 기능을 내장하고 있습니다.
OMS에선 utils/Ajax.ts 파일에 세팅이 되어있습니다.
Axios는 Promise 기반으로 javascript에서 제공하는 XMLHttpRequests를 만들어줍니다.
보통 Front-End에서 Back-End로 요청을 보낼 때 많이 사용되고, 혹은 외부 API를 받아오거나 크롤링을 할 때 사용합니다.

Promise란?

Promise는 javascript에서 비동기 작업을 처리하는 방법중에 하나입니다.
비동기 작업이 성공할 때와, 실패할 때를 나누어서 처리기를 연결해줄 수 있고,
보통은 axios와 같은 비동기 통신에서 자주 사용됩니다.
자세한 사용방법은 mdn Promise를 참고해주세요.

인스턴스 만들기

Axios는 인스턴스를 만들지 않고도 API 호출이 가능하지만,
인스턴스를 만들면 baseURL, timeout 등의 기본적인 설정이 가능하고,
또한 Interceptor를 적용시킬 수 있게 되어 편한 사용이 가능해집니다.

js
1import axios from 'axios';
2
3const ajax = axios.create({
4 baseURL: 'https://example.com/',
5 timeout: 1000,
6 headers: { 'Access-Control-Request-Headers': ['Authorization', 'Content-Type'] },
7}); // ajax라는 인스턴스를 생성해줌.

API 요청 보내기

인스턴스를 통한 요청 메서드는 아래와 같이 있습니다.
HTTP Methods에 대해서는 restful 포스트를 참조해주세요.
url은 반드시 들어가야하고, [] 이 부분에 들어가는 것은 선택사항입니다.

  1. ajax.get, ajax.delete

    ajax.get(url[,config]);
    get방식과 delete방식은 url에 query들이 담겨서 넘어가게 됩니다.
    주의하실점은 parameter가 브라우저에 따라 일정 글자 수 이상이 넘어가게 되면,
    에러가 발생할 수 있습니다.

    js
    1const config = {};
    2ajax.get('example', config);
  2. ajax.post, ajax.put, ajax.patch

ajax.post(url[,data[,config]]);
post, put, patch 방식은 request body에 데이터를 담아서 보내줍니다.

js
1const config = {};
2const responseBody = {};
3ajax.post('/example', responseBody, config);

config 세팅

config에는 request와 response에 대해서 다양한 세팅을 해줄 수 있는데,
자주 사용되는 것들에 대해서만 다루겠습니다.

js
1const config = {
2 // headers는 request header에 담길 값들을 지정해줍니다.
3 // back-end 설정에 맞춰 설정 데이터들을 넘길 수 있고, 인증토큰 값 등을 넘겨줍니다.
4 headers: {
5 'X-Requested-With': 'XMLHttpRequest',
6 Authorization: token,
7 },
8 // Get방식과 Delete 방식에서 많이 사용되며, url 옆에 쿼리를 붙혀줍니다.
9 // back-end에서는 @RequestParam, @PathVariable 등을 통해 값을 가져옵니다.
10 params: {
11 userId: 'X0134481',
12 },
13 // 인스턴스를 사용할땐 Delete방식에서만 사용됩니다.
14 // Delete 방식에서 param이 아닌 request body에 데이터를 넣어주고 싶을 때 사용합니다.
15 data: {
16 name: '유영진',
17 },
18 // paramsSerializer는 params의 시리얼라이즈를 담당하는 옵션 함수입니다.
19 // 데이터를 key[]=value1&key[]=value2로 보내는걸, key=value1&key=value2로 변경해줍니다.
20 paramsSerializer: (params) => qs.stringify(params, { arrayFormat: 'repaet' }),
21 // 요청이 시간 초과 되기 전의 시간을 지정합니다. 요청이 이 이상걸리면 요청을 중단합니다.
22 timeout: 1000,
23 // 자격증명을 이용하여 사이트간 제어 요청을 해야 하는지를 설정합니다.
24 withCredentials: false, //기본값
25 // status코드를 활용해 Promise를 이행할지, 거부할지를 결정합니다.
26 validateStatus: function (status) {
27 return status >= 200 && status < 300; // 기본값
28 },
29 // cancel 토큰은 아래에서 더 자세히 다룹니다.
30 cancelToken: source.token,
31};

응답

응답 정보는 promise의 결과에 return 됩니다.
응답 정보는 이행(then)에 담기게 됩니다.

js
1ajax.get('/test').then((response) => {
2 // 서버에서 보낸 데이터가 담깁니다.
3 console.log(response.data);
4 /* status code가 담깁니다. (200, 201, 204 등등…)
5 status code를 활용하여 insert 문을 사용할 중복체크 로직 등을 exception이 아닌 방식으로 구현 가능합니다.*/
6 if (response.status === 200) {
7 // OK 코드
8 console.log('중복 아이디');
9 } else if (response.status === 204) {
10 // Created
11 console.log('생성 완료');
12}
13// status를 code가 아닌 string으로 나타냅니다.
14console.log(response.statusText);
15// 서버에서 보낸 response header 값들을 볼 수 있습니다.
16console.log(response.headers);
17});

기본적인 사용법

OMS에서는 아래와 같은 방법으로 주로 사용합니다.

js
1import ajax, { ajaxHeaders, failure } from 'utils/Ajax';
2
3// Get 방식 요청
4const config = {
5 headers: ajaxHeaders,
6 params: {
7 company: 'SKHYNIX', // 넘겨줄 데이터
8 },
9};
10const success = (response) => {
11 console.log(response.data);
12};
13const doFinally = () => {
14 console.log('반드시');
15};
16ajax.get('url', config).then(success).catch(failure).finally(doFinally);
17
18// Post 방식 요청
19const responseBody = {
20 userId: 'show5116',
21 userName: '유영진',
22};
23const config = {
24 headers: ajaxHeaders,
25};
26const success = (response) => {
27 console.log(response.data);
28};
29const doFinally = () => {
30 console.log('반드시'); // 요청 성공 실패 여부를 떠나 반드시 실행해야 하는 함수
31};
32ajax.post('/url', data, config).then(success).catch(failure).finally(doFinally);

에러

OMS에서는 utils/ajax.ts에 faulure가 정의되어 있어서, 기본적으로는 가져다가 사용하면 됩니다.
하지만 특수한 상황에서는 에러메시지를 숨긴다던지, 혹은 실패했을 경우 다른 액션이 필요할 때,
혹은 에러가 나는 원인이 프론트엔드인지를 찾을 때, 직접 에러 핸들러를 추가해서 사용해주면 됩니다.

js
1ajax.get('/url').catch((error) => {
2 if (error.response) {
3 // 요청은 전송되었으나, 응답코드가 2xx가 아닐경우
4 console.log(error.response.data);
5 console.log(error.response.status);
6 console.log(error.response.headers);
7 } else if (error.request) {
8 // 요청은 전송되었는데, 응답이 수신되지 않았을 경우
9 console.log(error.request);
10 } else {
11 // 요청을 보내는데 실패한 경우(프론트엔드 문제)
12 console.log(error.message);
13 }
14});

interceptors

axios인스턴스를 만들면 interceptor를 적용시킬 수 있는데,
이로 인해 request 요청에 필요한 헤더를 편하게 세팅해주기도 하고,
response에서 오는 요청에 특별한 이벤트를 걸어줄 수 도 있습니다.

js
1// Interceptor를 사용하기 시작
2const requestInterceptor = ajax.interceptors.request.use(
3 (request) => {...} ,
4 (error) => {...}
5);
6const responseInterceptor = ajax.interceptors.response.use(
7 (response) => {...} ,
8 (error) => {...}
9);
10
11// Interceptor를 제거
12ajax.interceptors.request.eject(requestInterceptor);
13ajax.interceptors.response.eject(responseInterceptor);

현재 OMS에서는 로그인, 로그아웃, 그리고 토근에 관련되어서 interceptors가 사용되고 있고,
이는 auth 포스트에서 더 자세히 다룹니다.

요청취소

취소토큰을 이용해 취소가 필요할 때 요청 취소를 할 수 있습니다.
취소토큰은 지원중단된 proposal-cancelable-promises를 기반으로 하고 있습니다.
프론트에서 어떠한 동작에 의해서 취소시켜야 할 경우에만 사용할 것을 추천드리고,(요소를 제거)
xception에 대한건 백엔드에서 처리할 것을 추천드립니다.
사용 방법에는 2가지 방식이 있고, 코드스타일의 차이만 존재하고 기능은 같습니다.

source 방식

js
1const CancelToken = axios.CancelToken;
2const source = CancelToken.source();
3const config = {
4 cancelToken: source.token,
5};
6ajax.get(url, config).catch((error) => {
7 if (axios.isCancel(error)) {
8 console.log('캔슬되었습니다.' + error.message);
9 }
10});
11
12setTimeout(() => {
13 source.cancel('시간초과');
14}, 500);

생성자 방식

js
1const CancelToken = axios.CancelToken;
2let cancelRequest;
3const config = {
4 cancelToken: new CancelToken((c) => (cancelRequest = c)),
5};
6ajax.get(url, config).catch((error) => {
7 if (axios.isCancel(error)) {
8 console.log('캔슬되었습니다.' + error.message);
9 }
10});
11
12setTimeout(() => cancelRequest(), 500);