기본 설정이 적용된 axios의 '복사본'을 만드는 개념이다.
서로 다른 baseURL이나 설정이 필요한 경우 유용하다.
🖥️ javascript
// 실제로 생성된 axios 인스턴스 (개별 객체) 예시
const authApi = axios.create({
baseURL: 'https://auth.example.com',
timeout: 5000,
headers: {
'Content-Type': 'application/json'
}
});
const productApi = axios.create({
baseURL: 'https://product.example.com',
timeout: 3000,
headers: {
'Content-Type': 'application/json'
}
});
// 사용 예시
authApi.post('/login', { username, password });
productApi.get('/products');
🖥️ javascript
// 이것들이 각각 axios 인스턴스
const authApi = axios.create({...});
const productApi = axios.create({...});
const userApi = axios.create({...});
// createAxiosInstance는 위와 같은 인스턴스들을 생성하는 팩토리 함수
const authApi = createAxiosInstance('https://auth.example.com');
const productApi = createAxiosInstance('https://product.example.com');
const userApi = createAxiosInstance('https://user.example.com');
➡️ 각 인스턴스는 자신만의 고유한 설정(baseURL, timeout, headers 등)을 가진 독립적인 axios 객체다. 이렇게 생성된 인스턴스들은 서로 다른 API 엔드포인트나 설정을 가질 수 있으면서도, 인터셉터나 기본 설정 같은 공통 기능을 공유할 수 있다.
요청이나 응답을 보내기 전 또는 후에 가로채서 처리할 수 있는 기능이다.
공통적으로 처리해야 하는 로직을 중앙에서 관리할 수 있다.
🖥️ javascript
// 요청 인터셉터 예시
api.interceptors.request.use(
config => {
// 요청 보내기 전 공통으로 처리할 작업
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
// 로딩 상태 시작
store.dispatch(setLoading(true));
return config;
},
error => {
store.dispatch(setLoading(false));
return Promise.reject(error);
}
);
// 응답 인터셉터 예시
api.interceptors.response.use(
response => {
// 응답 데이터 처리
store.dispatch(setLoading(false));
return response;
},
error => {
store.dispatch(setLoading(false));
// 에러 공통 처리
if (error.response.status === 401) {
store.dispatch(logout());
router.push('/login');
}
if (error.response.status === 403) {
alert('권한이 없습니다');
}
return Promise.reject(error);
}
);
1. 인터셉터 없이 구현
🖥️ javascript
// API 호출마다 토큰 처리, 에러 처리 등을 반복해서 작성해야 합니다
const getUsers = async () => {
const token = localStorage.getItem('token');
try {
const response = await axios.get('/users', {
headers: { Authorization: `Bearer ${token}` }
});
return response.data;
} catch (error) {
if (error.response.status === 401) {
logout();
router.push('/login');
}
throw error;
}
};
const createUser = async (userData) => {
const token = localStorage.getItem('token');
try {
const response = await axios.post('/users', userData, {
headers: { Authorization: `Bearer ${token}` }
});
return response.data;
} catch (error) {
if (error.response.status === 401) {
logout();
router.push('/login');
}
throw error;
}
};
2. 인터셉터 사용
🖥️ javascript
// 인터셉터 설정 (한 번만 설정)
const api = axios.create({ baseURL: '/api' });
api.interceptors.request.use(config => {
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
api.interceptors.response.use(
response => response.data,
error => {
if (error.response.status === 401) {
logout();
router.push('/login');
}
return Promise.reject(error);
}
);
// API 호출 코드가 매우 간단해진다.
const getUsers = () => api.get('/users');
const createUser = (userData) => api.post('/users', userData);
🖥️ javascript
// API 로직에만 집중할 수 있음
const UserAPI = {
getUser: (id) => api.get(`/users/${id}`),
updateUser: (id, data) => api.put(`/users/${id}`, data),
deleteUser: (id) => api.delete(`/users/${id}`)
};
🖥️ javascript
// 모든 API 호출이 동일한 방식으로 처리됨
api.interceptors.response.use(
response => {
// 모든 응답에 대해 동일한 데이터 처리
logApiCall(response); // 로깅
setLoadingState(false); // 로딩 상태 관리
return response.data;
},
error => {
// 모든 에러에 대해 동일한 처리
handleApiError(error); // 에러 처리
setLoadingState(false); // 로딩 상태 관리
return Promise.reject(error);
}
);
🖥️ javascript
// 새로운 요구사항 추가가 쉬움
api.interceptors.request.use(config => {
// 새로운 요구사항: API 버전 헤더 추가
config.headers['API-Version'] = 'v2';
// 새로운 요구사항: 디바이스 정보 추가
config.headers['Device-Info'] = getDeviceInfo();
return config;
});
🖥️ javascript
// api/index.js
// 인스턴스 생성 팩토리 함수
const createAxiosInstance = (baseURL) => {
const instance = axios.create({
baseURL,
timeout: 5000,
headers: {
'Content-Type': 'application/json'
}
});
// 요청 인터셉터
instance.interceptors.request.use(
config => {
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
error => Promise.reject(error)
);
// 응답 인터셉터
instance.interceptors.response.use(
response => response.data,
error => {
switch (error.response.status) {
case 401:
handleUnauthorized();
break;
case 403:
handleForbidden();
break;
case 500:
handleServerError();
break;
}
return Promise.reject(error);
}
);
return instance;
};
// 여러 개의 API 인스턴스 생성
export const authApi = createAxiosInstance('https://auth.example.com');
export const productApi = createAxiosInstance('https://product.example.com');
이렇게 Instance와 Interceptor를 활용하면