[Axios] React에서 API 모듈화

bible_k_·2023년 7월 21일
2

✏️Moon의 속성 과외(?)를 듣고 공부하며 작성하는 글이다.

기존에는 컴포넌트 안에 api 요청과 에러 처리 모두 포함시켰다.
하지만 이렇게 하면 코드의 재사용성을 낮추고, 유지 보수도 힘들어진다.
프론트에서도 MVC패턴을 적용하여 구조를 분리하면 더 독립적이고 효율적으로 만들 수 있다.

Before

  const fetchData = async () => {
    try {
      const res = await axios.get('http://localhost:9090/posts');

      setPosts(res.data);
    } catch (error) {
      console.log(error);
    }
  };

컴포넌트 내에서 api 호출 및 응답을 처리하는 코드이다.
API가 모듈화되어있지 않고, MVC패턴으로 친다면 model, view, controller가 모두 한 곳에 있는 거나 마찬가지이다. 그만큼 생략될 수 있는 부분이 많고 활용도가 떨어진다.

Axios
Intercepter
Network service
Post controller (C)
useFetch류 (C+M)
view

이렇게 분리를 하고자 하는데, 오늘은 Axios, Intercepter, Network service 이 부분에 대해 다뤄보려고 한다.

after

NetworkService.ts

export default class NetworkService {
  //axios 인스턴스 생성
  instance: AxiosInstance | null = null;

  constructor() {
    this.instance = axios.create({
      baseURL: "http://localhost:9090",
    });
  }
  
  //인터셉터 설정
  initInterceptors() {
    //요청 인터셉터
    this.instance?.interceptors.request.use((config: any) => {
      return {
        ...config,
        headers: {
          ...config.headers,
          // "authorization": `Bearer ${accessToken}`
        },
      };
    });
	
    //응답 인터셉터
    this.instance?.interceptors.response.use(
    //응답에 대한 로직
      (response) => {
        return response.data;
      },
    //응답 에러 발생 시 수행할 로직
      async (error) => {
        const { config, status } = error;

        this.instance?.request({
          url: "/refesh/token",
          method: "POST",
        });
        return Promise.reject(error);
      }
    );
  }
	
  //http 메서드들
  get(url: string, config = {}) {
    return this.instance?.get(url, config);
  }

  post(url: string, data: any, config = {}) {
    return this.instance?.post(url, data, config);
  }
  put(url: string, data: any, config = {}) {
    return this.instance?.put(url, data, config);
  }
  delete(url: string, config = {}) {
    return this.instance?.delete(url, config);
  }
}

NetworkService 클래스를 간단하게 요약하면 다음과 같다.

  • 서버와의 통신에서 가장 접점에 있다.
  • Axios를 사용하여 HTTP 요청을 처리한다.
  • GET, POST, PUT, DELETE 등의 HTTP 요청 메서드를 제공한다.

구체적으로 뜯어보자!

  1. instance:
    Axios 인스턴스는 create()를 통해 생성할 수 있다.
    instance 항목에 baseUrl, headers, timeout 등 디폴트 값들을 작성해놓으면 여러번 작성할 필요 없어서 편리하다.
    axios 인스턴스

  2. constructor() 생성자:
    생성자 함수에서 instance에 Axios 인스턴스를 생성하여 할당한다.

  3. initInterceptors():
    initInterceptors() 메서드에서 Axios 인스턴스에 요청과 응답에 대한 인터셉터를 설정한다.
    요청 인터셉터 => axios.interceptors.request
    응답 인터셉터 => axios.interceptors.response
    위 코드에서 요청 인터셉터는 모든 요청 전에 실행되며, 인증 토큰과 같은 헤더 정보를 추가하는 작업을 수행한다.
    응답 인터셉터는 모든 응답을 처리하기 전에 실행되며, 응답의 데이터만 반환하도록 설정한다.
    또한 응답이 에러 상태 코드를 반환할 경우, 토큰을 리프레시하는 요청을 보내고 에러를 reject한다.

    interceptor란?
    Axios 라이브러리에서 제공하는 기능 중 하나로, HTTP 요청과 응답을 가로채고 변형할 수 있는 기능을 제공한다.
    interceptor는 then 이랑 catch로 처리되기 전, 요청(request) 또는 응답(response)을 가로 챌 수 있다.
    Interceptor를 사용하여 요청과 응답에 대해 공통적으로 수행해야 하는 작업을 중앙에서 관리하고, 코드 중복을 줄이고 유지보수를 용이하게 할 수 있다.

  4. HTTP 메서드 (get, post, put, delete):
    각각의 메서드는 Axios 인스턴스의 해당 HTTP 메서드를 호출하는 역할을 한다.

이렇게 NetworkService 클래스를 사용하면 API 요청을 간단하게 처리할 수 있으며, 인터셉터를 사용하여 요청 전후에 특정 작업을 수행할 수 있습니다. 또한 Axios의 장점을 활용하여 다양한 설정과 에러 처리를 할 수 있습니다.

profile
후론트엔드 개발자

0개의 댓글