axios 너 일로 와바

문강현·2025년 11월 10일

시작하며

오늘은 제가 프로젝트를 만들면서 자주 사용하게 될 axios에 대해 공부한 내용을 정리해보려고 합니다.
처음 날씨 api를 불러와 통신할 때는 fetch를 사용했지만
이번에는 보다 간결하고 다루기 쉬운 axios를 적용해보기로 했습니다.

axios란?

axios는 Node.js와 브라우저 모두에서 사용할 수 있는 Promise 기반의 HTTP 요청 라이브러리입니다.
간단히 말해, axios는 서버에 데이터를 요청하거나, 서버가 보낸 응답을 받아오는 도구라고 생각하면 됩니다.

용도
서버에 요청 보냄 -> 서버로부터 응답 받아옴
예시
로그인 요청, 유저 목록 가져오기, 게시글 등록, 클릭한 상품

이 모든 과정에서 axios를 사용할 수 있습니다.
프론트엔드와 백엔드가 데이터를 주고받을 때 필수적으로 활용되는 도구 중 하나입니다.

axios를 사용하는 이유

  • 코드가 간결하다
    같은 작업을 fetch로 구현하려면 then, JSON 변환, 에러 처리까지 많은 코드를 작성해야 하지만, axios는 비교적 단순하고 직관적인 문법을 제공합니다.

  • 자동 JSON 변환
    서버에서 JSON 데이터를 주고받을 때 별도의 변환 과정 없이 자동으로 처리됩니다.

  • 에러 처리 용이
    요청 실패 시 에러 상태 코드, 메시지 등 상세 정보를 쉽게 확인할 수 있어 디버깅할 때 유용합니다.

  • 인터셉터 지원
    요청 전/후에 특정 로직을 공통으로 넣을 수 있습니다. (예: 토큰 추가, 에러 처리 등)

  • 타임아웃 설정
    요청에 시간 제한을 걸어두어 일정 시간 내에 응답이 없으면 자동으로 오류 처리가 가능합니다.

기본적인 사용법

import axios from 'axios'

// GET 요청 (데이터 조회)
axios.get('/api/users')
  .then((response) => {
    console.log('유저 목록:', response.data)
  })
  .catch((error) => {
    console.error('에러 발생:', error)
  })

// POST 요청 (데이터 전송)
axios.post('/api/login', {
  id: 'testUser',
  password: '1234'
})
  .then((response) => {
    console.log('로그인 성공:', response.data)
  })
  .catch((error) => {
    console.error('로그인 실패:', error)
  })

axios는 Promise를 기반으로 하므로 .then()과 .catch()로 결과를 다룰 수 있습니다.
하지만 async/await 문법으로 조금 더 깔끔하게 작성할 수도 있습니다.

async/await 문법으로 작성하기

import axios from 'axios'

async function fetchUserList() {
  try {
    const response = await axios.get('/api/users')
    console.log('유저 목록:', response.data)
  } catch (error) {
    console.error('에러 발생:', error)
  }
}

fetchUserList()

async/await을 사용하면 코드 흐름이 동기적으로 보이기 때문에 가독성이 좋아지고 에러 처리 구조도 단순해집니다.
요즘은 대부분 async/await 방식으로 axios를 사용하는 경우가 많습니다.

기본 설정 (axios 인스턴스)

프로젝트가 커질수록 매번 주소를 적는 것이 번거로워집니다.
이럴 때는 axios 인스턴스를 만들어 baseUrl등 여러설정들을 등록해두면 좋습니다.

import axios from 'axios'

const api = axios.create({
  baseURL: 'https://my-project-server.com/api',
  timeout: 5000, // 요청 제한 시간 (ms)
  headers: {
    'Content-Type': 'application/json',
  },
})

export default api

이렇게 만들어둔 인스턴스를 사용하면

import api from './api'

// api.get('/users')
// api.post('/login')

처럼 간단하게 호출할 수 있습니다. 코드 중복이 줄고 유지보수도 쉬워집니다.

프로젝트 적용 중 생긴 문제

백엔드에서는 카테고리 값을 영문 Enum 형태로 관리하고 있었고 프론트엔드는 사용자가 보기 쉽게 한글 카테고리명을 보여주고 있었습니다.
그래서 프론트에서 선택한 한글 카테고리를 영어 코드로 변환해 전송해야 했습니다.

아래는 당시 프론트 쪽 코드의 일부입니다.

const categories = [
  '운동', '맛집', '동물', '여행', '영화',
  '게임', '독서', '공부', '음악', '🔞',
  '웹툰', '외향형', '내향형', '애니메이션'
];

const categoryMap = {
  운동: 'EXERCISE',
  맛집: 'RESTAURANT',
  동물: 'ANIMAL',
  여행: 'TRIP',
  영화: 'MOVIE',
  게임: 'GAME',
  독서: 'READING',  // 문제의 원인
  공부: 'STUDY',
  음악: 'MUSIC',
  '🔞': 'SEXUAL_PLEASURE',
  웹툰: 'WEBTOON',
  외향형: 'EXTROVERT',
  내향형: 'INTROVERT',
  애니메이션: 'ANIMATION',
};

그런데 회원가입 요청을 보낼 때 독서를 선택한 사용자만 회원가입이 실패하는 현상이 발생했습니다.
콘솔에서 확인해보니 API 응답이 500에러를 반환하고 있었습니다.

원인 분석
백엔드에서 사용하는 Enum 이름은 LEADING이었는데 프론트엔드에서는 READING으로 백엔드에서 오타가 나서 잘못 매핑되어 있었습니다.

프론트엔드와 백엔드 코드에 다음과 같은 차이가 있었습니다.

백엔드

프론트엔드

const categoryMap = {
  운동: 'EXERCISE',
  맛집: 'RESTAURANT',
  동물: 'ANIMAL',
  여행: 'TRIP',
  영화: 'MOVIE',
  게임: 'GAME',
  독서: 'READING',
  공부: 'STUDY',
  음악: 'MUSIC',
  '🔞': 'SEXUAL_PLEASURE',
  웹툰: 'WEBTOON',
  외향형: 'EXTROVERT',
  내향형: 'INTROVERT',
  애니메이션: 'ANIMATION',
};

이러한 불일치는 회원가입 시 유효성 검사 단계에서 거부되어 에러로 이어졌습니다.
눈으로 보면 금방 알 수 있지만 실제 프로젝트에서는 이런 부분이 쉽게 놓치기 쉽습니다.

문제 해결

우선 백엔드 Enum 리스트를 정확히 확인한 뒤 프론트에서 사용하는 categoryMap을 수정했습니다.

수정 후 다시 회원가입을 진행하니 문제가 완벽히 해결되었습니다.
회원가입 요청이 정상적으로 서버에 전달되고 선택한 카테고리들도 올바르게 저장되었습니다.

느낀 점

이번 문제를 통해 깨달은 건 프론트엔드와 백엔드 간 데이터 명세 일치가 얼마나 중요한가 또 소통의 중요성을 다시한번 느꼈습니다.
백엔드에서 Enum 값을 조금만 바꿔도 프론트엔드 로직이 바로 깨질 수 있기 때문에 api 명세서가 정확히 정리돼 있어야 합니다.

마치며

이번에 axios를 직접 적용해보면서 단순한 API 요청뿐 아니라 인터셉터, 인스턴스 설정, 에러 처리 등 다양한 기능이 있다는 걸 알게 되었습니다.
처음에는 fetch로도 충분하다고 생각했지만 실제 프로젝트에서는 axios의 편리함이 훨씬 크게 느껴졌습니다.

앞으로 axios 인스턴스와 인터셉터를 좀 더 적극적으로 활용하여 프로젝트를 잘 마무리 하도록 하겠습니다

0개의 댓글