axios 사용법 및 custom Instance와 Interceptors 개념
Axios에 대해 알아보자.
이 글을 작성하기 전 개인,팀 과제를 통해 axios를 사용했다. 앞으로도 자주 사용될 것 같아서 머리속에 각인이 되길 바라는 마음으로 정리해보도록 한다.
axios란 무엇인가?
- node.js와 브라우저를 위한 Promise 기반 http 클라이언트
- 즉, http를 이용해서 서버와 통신하기 위해 사용하는 패키지다.
1-1) 특징
-
promise 기반
- 비동기 처리를 위한
promise
를 지원하며async/await
와 함께 쉽게 사용할 수 있음
- 비동기 처리를 위한
-
JSON 데이터 자동 변환
- 서버로부터 받은 JSON 데이터를 자동으로 변환해 처리할 수 있음
-
인터셉터(Interceptors)
- 요청 또는 응답을 쌔벼서 특정 로직을 추가할 수 있음
-
요청 취소
-
CancelToken
을 사용해 요청을 취소할 수 있음
-
-
타임아웃 설정
- 요청 타임아웃을 설정할 수 있어, 너무 오래 기다리지 않도록 제어 가능함
axios 설치 방법
npm install axios # npm
yarn add axios # yarn
HTTP 메서드 사용법
Axios
는 다양한 HTTP 메서드를 지원함. 주로 사용하는 메서드는 GET, POST, PUT, DELTE, PATCH
가 있음
3-1) GET 요청
GET
메서드는 서버에서 데이터를 가져오는 데 사용하며 주로 데이터 조회 할 때 사용함
axios.get("/posts")
.then((response) => console.log(response.data))
.catch((error) => console.error(error));
// 비동기 처리
const fetchData = async () => {
try{
const response = await axios.get("/posts");
// data만 필요할 경우 구조 분해 할당(디스트럭처링)으로 처리해도 됌
// const { data } = await axios.get("/posts/");
console.log(response.data);
}catch(e){
console.log("error =>", e);
}
}
3-2) POST 요청
POST
메서드는 서버에 데이터를 전송하거나 새로운 데이터를 생성하는 데 사용함.
export const handleUserLogin = async (userData) => {
const response = await USER_API.post("/login", userData);
return response.data;
};
export const createTestResult = async (resultData) => {
await MBTI_API.post("/mbti", resultData)
};
3-3) PUT 요청
PUT
메서드는 서버에 있는 데이터를 완전히 교체할 때 사용함. (덮어쓰기임)
axios.put("/posts/1", { title: '변경 타이틀', content: '변경 내용' })
.then((response) => {
console.log('Post replaced:', response.data);
})
.catch((error) => {
console.error('axios put error', error);
});
3-4) DELETE 요청
DELETE
메서드는 서버에서 데이터를 삭제할 때 사용함.
export const deleteTestResult = async (id) => {
await MBTI_API.delete(`/mbti/${id}`)
};
3-4) PATCH 요청
PATCH
메서드는 서버에 있는 데이터를 부분적으로 수정할 때 사용함. (부분 업데이트임)
export const updateTestResultVisibility = async ({id, vis}) => {
console.log("visibility=>", vis);
await MBTI_API.patch(`/mbti/${id}`, {visibility: !vis})
};
Axios의 Custom Instance 사용법
4-1) Custom Instance 란?
커스텀 인스턴스는 여러 API 요청에서 동일한 설정을 재사용할 수 있게 해줌.
-
Base URL
,Headers
같은 공통 설정을 하나의 인스턴스에 정해두면 각 요청마다 반복새허 설정할 필요가 없음 - 프로젝트가 엄청 커서 axios를 1000번 사용한다 했을 때와 특히 갑자기 base URL이 변경되었을 때 생각해보면 됌 (1000번 일일이 수정해줄거냐 vs 한 곳에서 관리할꺼냐)
4-2) Custom Instance 적용
axios.create의 입력값으로 들어가는 객체는 configuration 객체이며 자세한 내용은 공식 문서를 참고!
// Custom Instance 만들기
// src/instance/baseInstance.js
import axios from 'axios';
export const USER_API = axios.create({
baseURL: "http://localhost:4000"
})
// App.jsx
import "./App.css";
import { useEffect } from "react";
import api from "./axios/api";
function App() {
useEffect(() => {
api
.get("/user")
.then((res) => {
console.log("결과 => ", res.data);
})
.catch((err) => {
console.log("오류가 발생하였습니다!");
});
}, []);
return <div>axios 예제입니다.</div>;
}
export default App;
Axios의 Interceptors 사용법
5-1) Interceptors란?
[출처 : https://javascript.plainenglish.io/how-to-implement-a-request-interceptor-like-axios-896a1431304a]
인터셉터는 요청
또는 응답
을 쌔벼서(가로채서), 추가 로직을 삽입할 수 있게 도와줌
- API 요청 전이나 응답을 받기 전/후에 특정 작업 수행이 가능함
- 예를 들어, 토큰 인증을 요청 헤더에 자동으로 추가 하거나, 에러 처리 로직을 응답 시 적용 가능
- 요청 헤더 추가
- 인증 관리
- 로그 관련 로직 삽입
- 에러 핸들링
5-2) Interceptor 적용
요청을 보낼 때와 응답을 받을 때 특정 작업을 수행하려면 아래와 같이 적용하면 됨
import axios from "axios";
const instance = axios.create({
baseURL: "http://localhost:4000",
});
instance.interceptors.request.use(
function (config) {
// 요청을 보내기 전 수행
console.log("인터셉트 요청 성공!");
return config;
},
function (error) {
// 오류 요청을 보내기 전 수행
console.log("인터셉트 요청 오류!");
return Promise.reject(error);
}
);
instance.interceptors.response.use(
function (response) {
console.log("인터셉트 응답 받았어요!");
// 정상 응답
return response;
},
function (error) {
console.log("인터셉트 응답 못받았어요...ㅠㅠ");
return Promise.reject(error);
}
);
export default instance;
5-3) 사용 예시 - 토큰/에러
Interceptor의 역할에 대해 간략한 설명을 추가하는 것이 좋다.
- 인텁세터는 Axios요청 또는 응답 전후에 특정 작업을 수행하며 이번 개인과제에서 겪었던 인증 토큰 추가나 오류 처리에도 유용하게 적용할 수 있을 것 같다.
// 토큰 처리 예시
instance.interceptors.request.use(
function (config) {
// 요청을 보내기 전 토큰을 헤더에 추가
const token = localStorage.getItem("token");
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
console.log("인터셉트 요청 성공!");
return config;
},
function (error) {
console.log("인터셉트 요청 오류!");
return Promise.reject(error);
}
);
// 에러 처리 개선
instance.interceptors.response.use(
function (response) {
console.log("인터셉트 응답 받았어요!");
return response;
},
function (error) {
if (error.response) {
switch (error.response.status) {
case 401:
console.log('인증되지 않았습니다! 로그인으로 리디렉션 중...');
// 로그인 페이지로 리디렉션
localStorage.removeItem('token');
window.location.href = '/login';
break;
case 404:
console.log('리소스를 찾을 수 없습니다');
break;
case 500:
console.log('서버오류');
break;
default:
console.log('오류가 발생함!');
}
} else {
// 응답이 없을 경우 네트워크 문제일 가능성
console.log("네트워크 오류 또는 서버가 응답하지 않습니다.");
}
return Promise.reject(error);
}
);
5-4) 인스턴스 + 인터셉터 활용
apiClient.js
import axios from 'axios';
const apiClient = axios.create({
baseURL: 'https://api.example.com',
timeout: 1000,
});
// 요청 인터셉터, 응답 인터셉터 설정
apiClient.interceptors.request.use(/* ... */);
apiClient.interceptors.response.use(/* ... */);
export default apiClient;
userApi.js
import apiClient from './apiClient';
// 사용자 관련 API 요청
export const getUserProfile = () => apiClient.get('/user/profile');
export const updateUserProfile = (data) => apiClient.patch('/user/profile', data);
authApi.js
import apiClient from './apiClient';
// 인증 관련 API 요청
export const login = (credentials) => apiClient.post('/auth/login', credentials);
export const logout = () => apiClient.post('/auth/logout');
App.jsx
import { getUserProfile, updateUserProfile } from './api/userApi';
import { login, logout } from './api/authApi';
// 사용자 프로필 가져오기
getUserProfile().then(response => console.log(response.data));
// 사용자 프로필 업데이트
updateUserProfile({ name: 'New Name' }).then(response => console.log(response.data));
// 로그인
login({ username: 'user', password: 'pass' }).then(response => console.log(response.data));
// 로그아웃
logout().then(response => console.log(response.data));
마무리
- Axios에서 제공하는 Interceptor 기능을 통해 요청 전/후에 특정 작업을 쉽게 추가할 수 있다.
- 매번 API 요청 시 JWT 토큰을 자동으로 추가하거나 응답 에러를 일관성 있게 처리할 수 있다.
- 이렇게 작성된 인터셉터는 모든 API 요청에 적용되어 코드의 중복을 줄이고, 오류를 효과적으로 관리할 수 있도록 도와줌.