[React] 아직 fetch만 고집하는 당신, axios를 사용해야 하는 이유

Jacob on the code·2021년 1월 17일
6

Better React

목록 보기
1/1

Intro

외부 API 사용

최근에 외부 api를 이용하는 업무를 맡게 됐다. 문서만 잘 되어 있다면 사용하는 것은 그리 크게 어렵지 않은 일이다. 이번에도 다르지 않았다.

이번에는 다음의 세 가지의 api를 사용했다.

  • 토큰을 생성한다
  • 생성된 토큰으로 리스트 데이터를 요청한다
  • 리스트 중 하나를 가져와 파싱 후 전송한다

fetch로만 열심히 짠 코드

// api.js
const URL = "https://api.com";

const encodeHeaders = {
  Content-Type: "application/x-www-form-urlencoded",
}

export const getToken = async () => {
  const response = await fetch(`${URL}/token`, {
    method: "POST",
    headers: encodeHeaders,
    body: {
      apikey: API_KEY,
      userid: USER_ID,
    }
  });
  const result = await response.json();
  return result.token;
}

export const getList = async (idx) => {
  const token = await getToken();
  const response = await fetch(`${URL}/list`,{
    method: "POST",
    headers: encodeHeaders,
    body: {
      apikey: API_KEY,
      userid: USER_ID,
      token,
    }
  })
  const result = await response.json();
  return result.list[idx]
}

export const sendSMS = async ({arg1, arg2}) => {
  const parsedData = parseArgs({arg1, arg2});
  const response = await fetch(`${URL}/sms`, {
    method: "POST",
    headers: encodedHeaders,
    body: {
      apikey: API_KEY,
      userid: USER_ID,
      token,
      data: parsedData,
    }
  })
  const result = await response.json();  
} 

지금 보니 보이는 리팩토링 요소

  • 동일한 headers, method, body를 매번 입력한다.
  • getList 함수를 실행하기 전에 토큰을 매번 받아 온다.
  • body에 공통된 동일한 값을 반복해서 입력한다.

하루 만에 빠르게 업무를 처리한 후 나와 같은 API를 이용해서 사용하는 종택님과 코드를 비교하면서 같이 보게 됐다. 그러다 axios의 엄청난 기능을 만나게 됐다!

axios와의 만남

나에게 axios는 여러 많은 굳이? 중 하나 였다. fetch로도 다 구현할 수 있는데 굳이 axios를 써야 하나? 하지만 나는 생각하지 못했다... 굳이 axios를 사용하는 이유가 있지 않을까?

이번주에도 거의 2천만명이 다운 받아 사용했네...

axios instance

api call에 대한 instance를 생성해서 하나의 instance로 여러 번의 요청을 관리할 수 있게 된다.

인스턴스 생성

const instance = axios.create({
  baseURL: BASE_URL, // "https://api.com"
  headers: encodeHeaders,
  data: {
    apikey: API_KEY,
    userid: USER_ID,
  }
})

인스턴스에 기본 base url와 headers와 공통된 body가 정의되어 있으므로 이후에는 end point만 추가하면 된다. data는 body에 담을 데이터가 들어 간다.

export const getToken = async () => {
  const response = await instance.post("/token");
  const result = await response.json();
  instance.defaults.data = {...instance.defaults.data, token: result.token}
}

export const getList = async (idx) => {
  const response = await instance.post("/list")
  const result = await response.json();
  if(result.list){
    return result.list[idx];
  }
}

export const sendSMS = async ({arg1, arg2}) => {
  const parsedData = parseArgs({arg1, arg2});
  const response = await axios.post('/sms', { data: parsedData })
  const result = await response.json();  
} 
  • 하나의 인스턴스를 여러 번 사용하면서 정보를 계속 업데이트 할 수 있어서 유용한 것 같다. 코드도 훨씬 깔끔해졌다.
  • 토큰이 만료됐을 때, 요청이 실패했을 때 로직을 추가해야겠다. (interceptor를 이용 해보자)

Outro

아직 axios의 더 다양한 기능을 사용해보진 못했지만 여태 왜 axios를 안썼나 싶었을 정도로 정말 유용하다.
이전 회사에서 오랫동안 1인 개발을 하다 보니 효율적인 코드를 짜는 것보다는 익숙한 방법과 코드로 빠르게 업무를 처리하기에 급급했던 것 같다.

  • 굳이? 라고 생각이 드는 것도 한 번 제대로 써보기나 하고 판단하자.
  • 유능한 동료분들과 코드에 대해 좀 더 얘기하는 시간을 많이 갖자.
profile
Swift, Kotlin에 미련 가득한 React Native 개발자

4개의 댓글

comment-user-thumbnail
2021년 1월 18일

감사합니다

답글 달기
comment-user-thumbnail
2021년 1월 21일

안녕하세요 관희님! sendSMS 안에 있는 parseArgs는 앞서 직접 정의하신 함수인가요? 잘 몰라서 구글링해보니까 인자값을 처리하는 파이썬 내장함수라고 하는데 여기선 어떤 의도로 쓰신 건지 알 수 있을까요~?

2개의 답글