상세 컨텐츠

본문 제목

React axios 모듈화

Front/React

by Chan.94 2025. 2. 7. 13:47

본문

반응형

fetch, axios 기본 개념

기본 제공 여부

  • Fetch: 브라우저에 내장된 JavaScript API로 별도의 설치가 필요 없다.
  • Axios: 외부 라이브러리로 사용하기 전에 설치가 필요하다
npm install axios

 

기능 차이

 Fetch

  • 기본적인 HTTP 요청만 제공
  • 요청과 응답 처리 시 JSON 변환 등을 수동으로 처리해야 함
  • 요청 타임아웃, 응답 데이터 변환 등의 고급 기능은 직접 구현해야 함
fetch('https://api.example.com/data')
  .then(response => {
    if (!response.ok) {
      throw new Error('Network response was not ok');
    }
    return response.json();
  })
  .then(data => console.log(data))
  .catch(error => console.error('Fetch error:', error));

 

Axios

  • 기본적으로 JSON 응답을 처리하며, 사용자가 반복적으로 작성할 코드를 줄여줌
  • Response는 Promise 객체로 반환된다.
  • 타임아웃 설정, 자동으로 CSRF 토큰 전송, 인터셉터(interceptors) 등 고급 기능을 제공
import axios from 'axios';

axios.get('https://api.example.com/data')
  .then(response => console.log(response.data))
  .catch(error => console.error('Axios error:', error));

 

에러 처리

  • Fetch
    • HTTP 에러(예: 404, 500)는 response.ok를 통해 수동으로 확인해야 함
    • 네트워크 에러(예: 인터넷 연결 실패)만 catch로 처리됨
  • Axios
    • HTTP 에러와 네트워크 에러 모두 catch 블록에서 처리됨
    • 더 나은 에러 정보를 제공함

정리

기능 Fetch Axios
내장 여부 브라우저 기본 제공 외부 라이브러리 설치 필요
JSON 응답 자동 처리 ❌ (response.json() 필요)
HTTP 에러 처리 ❌ (직접 확인 필요)
요청 타임아웃 지원 ❌ (직접 구현 필요) ✅ (기본 제공)
인터셉터 기능

axios 모듈화 - Step(1)

axios.js 전체 소스

더보기
import axios from 'axios';

// Axios 인스턴스 생성
const axiosInstance = axios.create({
    baseURL: '/main-dev',   // 프록시 경로
    //timeout: 5000,          // 요청 타임아웃 설정 (ms)
    headers: {
      'Content-Type': 'application/json',
    },
});

// 요청 인터셉터
axiosInstance.interceptors.request.use(
    (config) => {
      // 요청 헤더 설정
      return config;
    },
    (error) => {
      return Promise.reject(error);
    }
);
  
// 응답 인터셉터
axiosInstance.interceptors.response.use(
    (response) => {
        //응답에 대한 로직
        const res = response.data;

        console.log(res);
        if (res.error) {
            console.log("api error : " + res.error);
        }

        return res;
    },
    async (error) => {
        const originalRequest = error.config;
        console.log(error.response)
        return Promise.reject(error);
    }
);
  
export default axiosInstance;​

 

Axios 인스턴스 생성

const axiosInstance = axios.create({
    baseURL: '/main-dev',   // 프록시 경로
    timeout: 5000,          // 요청 타임아웃 설정 (ms)
    headers: {
      'Content-Type': 'application/json',
    },
});

create 메서드를 사용하면 axios 인스턴스를 생성할 수 있으며 이를 이용하여 공통 속성이나 인터셉터 등을 설정할 수 있다.

 

인터셉터 핸들링
HTTP 요청할 때와 응답을 받을 때에 인터셉터를 이용하여 핸들링을 할 수 있는 것이 axios의 특징이다.

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

 

  • 응답 인터셉터
// 응답 인터셉터 추가하기
axiosInstance.interceptors.response.use(
  function (response) {
    // 응답 데이터가 있는 작업 수행
    return response
  },
  function (error) {
    // 응답 오류가 있는 작업 수행
    return Promise.reject(error)
  },
)

 

AxiosTest.js

import axiosInstance from './api/axios';
import React, {useState, useEffect} from 'react';

function AxiosTest() {
  const [message, setMessage] = useState("");

  useEffect( () => {
        requestPost();
        },[])

  const requestPost = async () => {
    const res = await axiosInstance.post('/devlog/jpa/selectUserAll', );
    console.log(res);
    setMessage(res.data[2].email);
  }

  return (
    <>
      <p>
        {message}
      </p>
    </>
  );
}

export default AxiosTest;

axios를 모듈화 하였기 때문에 응답데이터가 일관되게 반환될 것이다.

 

axios 인스턴스 메서드

axios.get(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])
axios.delete(url[, config])
axios.request(config)
axios.head(url[, config])
axios.options(url[, config])
axios.getUri([config])

 

axios conifg 설정

url 속성만 필수이고, 나머지 속성은 옵션입니다. method가 지정되지 않으면 요청은 GET으로 기본 설정 됨

{
  // `url`은 요청에 사용될 서버 URL입니다.
  url: '/user',

  // `method`는 요청을 할 때 사용될 메소드 이름입니다.
  method: 'get', // 기본

  // `url` 속성 값이 절대 URL이 아니라면, `url` 앞에 `baseURL`이 붙습니다.
  // axios 인스턴스가 상대 URL을 해당 인스턴스의 메소드에 전달하도록
  // `baseURL`을 설정하는 것이 편리 할 수 있습니다.
  baseURL: 'https://some-domain.com/api/',

  // `transformRequest`는 서버에 보내기 전에 요청 데이터를 변경할 수 있습니다.
  // 요청 메소드 'PUT', 'POST' 및 'PATCH' 에만 적용 가능합니다.
  // 배열의 마지막 함수는 버퍼(buffer)의 문자열이나 인스턴스를 반환해야 합니다.
  // ArrayBuffer, FormData 또는 Stream 헤더 객체를 수정할 수 있습니다.
  transformRequest: [function (data, headers) {
    // 데이터 변환 수행 후, 반환
    // ...
    return data;
  }],

  // `transformResponse`는 응답할 데이터에 대한 변경을 전달해
  // then/catch에 전달하도록 허용합니다.
  transformResponse: [function (data) {
    // 데이터 변환 수행 후, 반환
    // ...
    return data;
  }],

  // `headers`는 서버에 전송 될 사용자 정의 헤더 입니다.
  headers: { 'X-Requested-With': 'XMLHttpRequest' },

  // `params`는 요청과 함께 전송 될 URL 매개 변수입니다.
  // 일반 객체 이거나 URLSearchParams 객체여야 합니다.
  params: {
    ID: 12345
  },

  // `paramsSerializer`는`params`를 직렬화(serializing) 하는 옵션 함수입니다.
  // (예: https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/)
  paramsSerializer: function (params) {
    return Qs.stringify(params, {arrayFormat: 'brackets'})
  },

  // `data`는 요청 본문(request body)으로 전송할 데이터입니다.
  // 'PUT', 'POST' 및 'PATCH' 요청 메소드에만 적용 가능합니다.
  // 'transformRequest`가 설정되지 않은 경우 다음 유형 중 하나여야 합니다.
  // - [ string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams ]
  // - 브라우저 전용: FormData, File, Blob
  // - Node.js 전용: Stream, Buffer
  data: {
    firstName: 'Fred'
  },

  // `timeout`은 요청이 타임 아웃되는 밀리 초(ms)를 설정합니다.
  // 요청이`timeout` 설정 시간보다 지연될 경우, 요청은 중단됩니다.
  timeout: 1000, // 기본 값: `0` (타임아웃 없음)

  // `withCredentials`는 자격 증명(credentials)을 사용하여
  // 크로스 사이트 접근 제어(cross-site Access-Control) 요청이 필요한 경우 설정합니다.
  withCredentials: false, // 기본 값

  // `adapter`는 테스트를 보다 쉽게 해주는 커스텀 핸들링 요청을 허용합니다.
  // 유효한 응답(Promise)을 반환해야 합니다. (lib/adapters/README.md 참고).
  adapter: function (config) {
    // ...
  },

  // `auth`는 HTTP 기본 인증(auth)이 사용되며, 자격 증명(credentials)을 제공함을 나타냅니다.
  // 기존의 `Authorization` 커스텀 헤더를 덮어쓰는 `Authorization` 헤더(header)를 설정합니다.
  auth: {
    username: 'janedoe',
    password: 's00pers3cret'
  },

  // `responseType`은 서버에서 응답할 데이터 타입을 설정합니다.
  // [ 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream' ]
  responseType: 'json', // 기본 값

  // `responseEncoding`은 응답 디코딩에 사용할 인코딩을 나타냅니다.
  // [주의!] 클라이언트 사이드 요청 또는 `responseType`이 'stream'인 경우는 무시합니다.
  responseEncoding: 'utf8', // 기본 값

  // `xsrfCookieName`은 xsrf 토큰(token)에 대한 값으로 사용할 쿠키 이름입니다.
  xsrfCookieName: 'XSRF-TOKEN', // 기본 값

  // `xsrfHeaderName`은 xsrf 토큰 값을 운반하는 HTTP 헤더 이름입니다.
  xsrfHeaderName: 'X-XSRF-TOKEN', // 기본 값

  // `onUploadProgress`는 업로드 프로그래스 이벤트를 처리합니다.
  onUploadProgress: function (progressEvent) {
    // 네이티브 프로그래스 이벤트(Native Progress Event) 처리 코드
    // ...
  },

  // `onDownloadProgress`는 다운로드 프로그래스 이벤트를 처리합니다.
  onDownloadProgress: function (progressEvent) {
    // 네이티브 프로그래스 이벤트(Native Progress Event) 처리 코드
    // ...
  },

  // `maxContentLength`는 HTTP 응답 콘텐츠의 최대 크기를 바이트(Bytes) 단위로 설정합니다.
  maxContentLength: 2000,

 // `validateStatus`는 주어진 HTTP 응답 상태 코드에 대한 약속을 해결할지 거절 할지를 정의합니다.
 // `validateStatus`가`true`를 반환하면 (또는`null`,`undefined`) promise를 resolve 합니다.
 // 그렇지 않으면 promise가 reject 됩니다.
  validateStatus: function (status) {
    return status >= 200 && status < 300; // 기본 값
  },

  // `maxRedirects`는 Node.js에서 리디렉션 가능한 최대 갯수를 정의합니다.
  // 0으로 설정하면 리디렉션이 수행되지 않습니다.
  maxRedirects: 5, // 기본 값

  // `socketPath`는 Node.js에서 사용될 UNIX 소켓을 정의합니다.
  // 예: '/var/run/docker.sock'을 사용하여 docker 데몬에 요청을 보냅니다.
  // `socketPath` 또는`proxy`만이 지정 될 수 있습니다.
  // 둘 다 지정되면`socketPath`가 사용됩니다.
  socketPath: null, // 기본 값

  // `httpAgent`와`httpsAgent`는 각각 Node.js에서 http와 https 요청을 수행 할 때
  // 사용할 커스텀 에이전트를 정의합니다. 이것은 기본적으로 활성화되지 않은 `keepAlive`와 같은
  // 옵션을 추가 할 수 있게 합니다.
  httpAgent: new http.Agent({ keepAlive: true }),
  httpsAgent: new https.Agent({ keepAlive: true }),

  // 'proxy'는 프록시 서버의 호스트 이름과 포트를 정의합니다.
  // 기존의 `http_proxy` 및 `https_proxy` 환경 변수를 사용하여 프록시를 정의 할 수도 있습니다.
  // 프록시 설정에 환경 변수를 사용하고 있다면 `no_proxy` 환경 변수를 쉼표로 구분 된 도메인 목록으로
  // 정의하여 프록시 할 필요가 없습니다.
  // 환경 변수를 무시하고 프록시를 사용하지 않으려면 `false`를 설정합니다.
  // `auth`는 HTTP 기본 인증(Basic Auth)를 사용하여 프록시에 연결하고 자격 증명을 제공해야 함을 나타냅니다.
  // 기존의 `Proxy-Authorization` 커스텀 헤더를 덮어쓰는 `Proxy-Authorization` 헤더(header)를 설정합니다.
  proxy: {
    host: '127.0.0.1',
    port: 9000,
    auth: {
      username: 'mikeymike',
      password: 'rapunz3l'
    }
  },

  // `cancelToken`은 요청을 취소하는 데 사용할 수 있는 취소 토큰을 지정합니다.
  // (자세한 내용은 해제(Cancellation) 섹션 참조).
  cancelToken: new CancelToken(function (cancel) {
    // ...
  })

}

axios 모듈화 - Step(2)

axios.js 전체소스

더보기
import axios from 'axios';

// Axios 인스턴스 생성
const axiosInstance = axios.create({
    baseURL: '/main-dev',   // 프록시 경로
    //timeout: 5000,          // 요청 타임아웃 설정 (ms)
    headers: {
      'Content-Type': 'application/json',
    },
});

// 요청 인터셉터
axiosInstance.interceptors.request.use(
    (config) => {
      // 요청 헤더 설정
      return config;
    },
    (error) => {
      return Promise.reject(error);
    }
);

// 공통 요청 함수
const axiosRequest = async (method, url, data = null, fn_callback, bResponseOnlyData = true) => {

    try {
        const response = await axiosInstance({
            method,
            url,
            data,
        });
        
        if(response == null){
            return ;
        }

        var res = response;
        console.log(res);

        if(bResponseOnlyData){
            res = res.data.data;
        }

        // 서버에서 응답을 받았지만 status가 200이 아닌경우
        if(response.data.status !== 200){
            fn_axiosError(new Error(`[${response.data.status}] ${response.data.message}`));
            return;
        }

        if (fn_callback && typeof fn_callback === "function") {
            fn_callback(res);
        }
    } catch (error) {
        fn_axiosError(error);
    }
};

const fn_axiosError = async(error) => {

    const originalRequest = error.config;

    // 기타 에러 처리
    console.log(error);
}

export default axiosRequest; // 기본 익스포트 사용

axiosRequest - 공통 요청 처리 함수 

  • 코드 중복 감소
    • 각 컴포넌트에서 axios를 직접 설정할 필요 없이 request 함수를 호출.
  • 유지보수 용이
    • try-catch로 묶어서 공통으로 API 요청을 처리하기 위함
    • API 요청 이후 로직은 공통 함수 호출 시 전달받은 함수 파라미터를 호출하도록 함

fn_axiosError - error 공통 처리

  • API 요청에 대한 Error 공통 처리
  • refresh token까지 만료되었을 경우 로그인 화면으로 이동
  • 로그인, Modal 개발 후 Alert처리 및 화면 이동 로직 추가 예정

AxiosTest.js

import axiosRequest from '../api/axios';
import React, {useState, useEffect} from 'react';

function AxiosTest() {
  const [message, setMessage] = useState("");

  useEffect( () => {
        requestPost();
        },[])

  const requestPost = () => {
    axiosRequest("post"
                , "/devlog/jpa/selectUserAll"
                , {}
                , fn_callback
                , false
    );
  }
  
  const fn_callback = (response) => {
    setMessage(res.data[2].email);
  }

  return (
    <>
      <p>
        {message}
      </p>
    </>
  );
}

export default AxiosTest;

마무리

백엔드 서버와 통신을 위해 axios를 사용할 것이며 모듈화 하여 일관되게 관리할 환경이 되었다.

 


이전글

다음 글

  •  
반응형

'Front > React' 카테고리의 다른 글

React 로그인 구현 (JWT)  (1) 2025.02.09
React Modal 구현하기 (Alter, Loading)  (1) 2025.02.08
React-Router-Dom 정리  (0) 2025.02.06
React Hook 기본 정리 / Custom Hook  (1) 2025.02.05
React CORS 설정 - 프록시 (http-proxy-middleware)  (7) 2025.01.31

관련글 더보기

댓글 영역

>