[PPLOG] Axios 세팅하기

김현중·2024년 9월 16일

PPLOG

목록 보기
2/14
post-thumbnail

카카오 엔터프라이즈 5기 먀옹팀의 프로젝트 PPLOG의 프론트엔드 기본 세팅 과정입니다.

📡Axios 세팅

Axios란 무엇인가?

Axios는 브라우저와 Node.js 환경에서 모두 사용할 수 있는 Promise 기반 HTTP 클라이언트 입니다. 주로 REST API와 통신하거나 비동기 요청을 처리하기 위해 사용되며, 쉽게 HTTP 요청을 만들고 관리할 수 있게 도와줍니다.

Axios의 특징

1. Promise 기반 비동기 요청

  • Axios는 Promise 기반으로 동작해 then, catch를 사용해 비동기 요청 결과를 처리합니다. 그리고 async/await 문법을 사용할 수 있어 비동기 처리 로직을 직관적으로 작성할 수 있습니다.

2. 요청 및 응답 인터셉터

  • Axios는 인터셉터 기능을 제공하여 HTTP 요청 또는 응답을 가로채고, 추가 로직을 실행할 수 있습니다.
    이를 통해 요청 전 헤더에 토큰을 추가하거나, 응답 오류를 일괄적으로 처리하는 등 다양한 전처리 및 후처리 작업을 수행할 수 있습니다.
axios.interceptors.request.use(config => {
  config.headers.Authorization = `Bearer ${token}`;
  return config;
});

3. 자동으로 JSON 데이터 처리

  • Axios는 요청 본문을 자동으로 JSON 형식으로 변환하여 전송하고, 서버로부터 받은 응답도 자동으로 JSON으로 파싱합니다.

4. 타임아웃 및 취소 기능

  • Axios는 요청 타임아웃을 설정할 수 있어, 특정 시간 내에 응답이 오지 않으면 요청을 자동으로 취소합니다.

세팅하기

다음 명령어를 사용해 Axios를 npm install합니다.

npm install axios

Axios 사용 방법

아직 실제 api가 없으므로 아래부터 예제 코드로 대체합니다.

1. GET 요청

axios.get('api/get')
	.then(response => {
  		console.log(response.data);	// 서버로 부터 받은 데이터
	})
	.catch(error => {
  		console.error(error); // 오류 처리
});

2. POST 요청

axios.post('api/post', {
  	name: '김현중',
  	major: '컴공',
})
	.then(response => {
  		console.log(response.data); // 서버의 응답 처리
	})
	.catch(error => {
  		console.error(error); // 오류 처리
});

3. async/await을 사용한 비동기 처리

async function getData() {
  try{
    const response = await axios.get('api/get');
    console.log(response.data);
  } catch (error) {
    console.error(error);
  }
}

4. 요청에 헤더 추가

axios.get('/api/get', {
  headers: {
    Authorization: 'Bearer token'
  }
})
	.then(response => {
  		console.log(response.data);
	})
	.catch(error => {
  		console.error(error);
}));

왜째서 fetch api가 아닌 Axios를 사용하지??

🤷‍♂️도대체 왜 브라우저에 내장된 fetch api를 사용하지 않고 Axios를 사용하는지 궁금해하는 저 자신을 위해 Axios와 fetch api의 차이점을 가져왔습니다.

1. JSON 데이터 처리 차이

  • Axios는 서버로부터 받은 JSON을 자동으로 파싱합니다.
axios.get('/api/get')
	.then(response => {
  		console.log(response.data);	// 자동으로 JSON 파싱
});
  • fetch api는 수동으로 response.json()을 호출해 데이터를 파싱합니다.
fetch('/api/get')
	.then(response => response.json())
	.then(data => console.log(data));

2. 요청 및 응답 인터셉터

  • Axios는 요청과 응답을 가로채 추가 처리를 할 수 있는 인터셉터 기능을 제공합니다. 그러나 fetch api는 기본적으로 이런 기능을 제공하지 않아, 요청 전후 추가 작업을 하려면 별도의 로직을 작성해야 합니다.

3. 타임아웃 기능

  • Axios는 기본적으로 타임아웃 설정을 지원합니다. 특정 시간 내에 응답이 없으면 요청을 취소합니다.
axios.get('api/get', { timeout: 5000 })
	.catch(error => console.log('요청 타임 아웃'));
  • fetch api는 타임아웃 기능이 내장되어 있지 않으므로, 별도의 타임아웃 로직을 추가로 작성해야합니다.
// AbortController를 사용한 예시
const controller = new AbortController();
const timeoutId = setTimeout(()=> constroller.abort(), 5000);

fetch('/api/get', { signal: controller.signal })
	.catch(error => console.log('요청 타임 아웃'));


🍔Axios 인스턴스 세팅

Axios 인스턴스란 무엇인가?

Axios 인스턴스는 Axios에서 제공하는 기능 중 하나로, 여러 개의 HTTP 요청에서 공통으로 사용되는 설정을 모아 재사용 가능한 인스턴스를 생성하는 방식입니다.

예를 들면 공통 헤더, 베이스 URL, 타임아웃 설정 등을 한 번에 적용할 수 있습니다.

세팅하기

먼저, Axios 인스턴스를 생성하려면 axios.create() 메서드를 사용합니다. 이 메서드는 공통 설정을 포함한 새로운 Axios 인스턴스를 반환합니다.

const config = {
  backend: {
    baseURL: process.env.NEXT_PUBLIC_BASE_URL,
  },
};

const server = config.backend.baseURL;

const axiosInstance: AxiosInstance = axios.create({
  baseURL: server,	// 기본 URL
  timeout: 5000,  // 요청 타임아웃 시간 설정 (5초)
  withCredentials: true,
  headers: {
    'Content-Type': 'application/json',  // 모든 요청에 적용할 기본 헤더
    Authorization: 'Bearer your-token',  // 인증 토큰
  },
});

사용하기

Axios 인스턴스를 생성한 후에 axiosInstance를 사용하여 요청을 보낼 수 있습니다.
axiosInstance.get(), axiosInstance.post()등 메서드는 기본 Axios와 같습니다.

  • GET 요청
axiosInstance.get('/get')
	.then(response => {
  		console.log(response.data);
	})
	.catch(error => {
  		console.error('get 에러 발생', error);
});
  • POST 요청
axiosInstance.post('/post', {
  name: '김현중',
  major: '컴공',
})
	.then(response => {
  		console.log('Post 성공: ', response.data);
})
	.catch(error => {
  		console.error('post 에러 발생', error);
});

위 두 예시에서 요청 주소는 process.env.NEXT_PUBLIC_BASE_URL/getprocess.env.NEXT_PUBLIC_BASE_URL/post가 됩니다. 그리고 모든 요청에 미리 정의한 헤더(Content-TypeAuthorization)가 포함됩니다.


인터셉터와 함께 사용하기

Axios 인스턴스를 사용할 때에도 인터셉터를 추가하여 모든 요청이나 응답을 가로채 특정 로직을 실행할 수 있습니다.

  • 요청 인터셉터
axiosInstance.interceptors.request.use(
  config => {
    // 요청 전에 수행할 작업(동적으로 토큰 추가)
    const token = localStorage.getItem('authToken');
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  error => {
    // 요청 오류 발생 시 처리
    return Promise.reject(error);
  }
);
  • 응답 인터셉터
axiosInstance.interceptors.response.use(
  response => {
    // 응답 데이터 가공
    return response;
  },
  error => {
    // 오류 응답을 공통으로 처리
    if (error.response.status === 401) {
      console.error('!인증 오류! 로그인 페이지로 이동합니다');
    }
    return Promise.reject(error);
  }
);

인터셉터를 사용해 모든 요청과 응답에 대한 공통 처리를 구현한 예제입니다. 401 오류 등의 응답이 발생하면 로그인 페이지로 이동하는 로직을 추가할 수 있습니다.

인스턴스와 인터셉터는 Axios 인스턴스 생성 파일에 같이 선언 후 export default를 사용해 내보내기 하면 됩니다.


!사용해보자!

아래는 인스턴스를 생성하고, 사용하는 예시입니다.

  • api/axiosInstace.ts
import axios, { AxiosInstance } from 'axios';

const config = {
  backend: {
    baseURL: process.env.NEXT_PUBLIC_BASE_URL,
  },
};

const server = config.backend.baseURL;

// Axios 인스턴스 생성
const axiosInstance: AxiosInstance = axios.create({
  baseURL: server,
  timeout: 1000,
  headers: {
    'Content-Type': 'application/json',	// JSON 형식으로 통신
  },
});

// 요청 인터셉터 추가
axiosInstance.interceptors.request.use(
  config => {
    const token = localStorage.getItem('authToken');
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;	// 동적으로 인증 토큰 추가
    }
    return config;
  },
  error => Promise.reject(error)
);

// 응답 인터셉터 추가
axiosInstance.intercepotrs.response.use(
  response => response,
  error => {
    if (error.response.status === 401) {
      // 인증 실패 처리
      console.error('!인증 오류! 로그인 페이지로 이동합니다');
    }
    return Promise.reject(error);
  }
);

export default axiosInstance;
  • api/apiService.ts (API 서비스 파일)
import axiosInstance from './axiosInstance';

// 사용자 목록 가져오기
export const fetchUsers = async () => {
  try {
    const response = await axiosInstance.get('/users');
    return response.data;
  } catch (error) {
    console.error('유저 정보 get 실패: ', error);
    throw error;
  }
};

// 사용자 생성
export const createUser = async (userData: { name: string; major: string}) => {
  try {
    const response = await axiosInstance.post('/users', userData);
    return response.data;
  } catch (error) {
    console.error('유저 생성 post 실패: ', error);
    throw error;
  }
};
  • 사용하는 곳에서
import { fetchUsers, createUser } from './api/apiService';

const fetchEntireUsers = async () => {
  await fetchUsers();
};

const addUser = async () => {
  const newUser = { name: '김현중', major: '컴공' };
  await createUser(newUser);
};
profile
진짜 성실한 사람

0개의 댓글