Axios 개요 및 설치
Vue.js 애플리케이션에서 비동기 HTTP 통신을 구현할 때 Axios는 가장 널리 사용되는 Promise 기반의 클라이언트 라이브러리입니다. 브라우저와 Node.js 환경 모두에서 원활하게 작동하며, 직관적인 API를 제공합니다.
패키지 설치
프로젝트 환경에 맞는 패키지 매니저를 사용하여 Axios를 설치할 수 있습니다.
# npm 사용
npm install axios
# yarn 사용
yarn add axios
# pnpm 사용
pnpm add axios
또는 빌드 도구를 사용하지 않는 환경에서는 CDN을 통해 스크립트를 직접 로드할 수 있습니다.
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
기본 HTTP 메서드 활용
GET 요청 및 데이터 바인딩
서버로부터 데이터를 가져와 Vue 컴포넌트의 상태에 바인딩하는 기본적인 GET 요청 예시입니다. 라이프사이클 훅인 mounted 내에서 호출합니다.
new Vue({
el: '#dashboard',
data() {
return {
platformList: [],
isLoading: false
};
},
async mounted() {
this.isLoading = true;
try {
const { data } = await axios.get('https://api.example.com/v1/platforms');
this.platformList = data.items;
} catch (err) {
console.error('데이터 조회 중 오류 발생:', err.message);
} finally {
this.isLoading = false;
}
}
});
URL에 쿼리 파라미터를 전달할 때는 params 객체를 활용하는 것이 가독성과 유지보수 측면에서 유리합니다.
axios.get('https://api.example.com/v1/users', {
params: {
userId: 98765,
role: 'admin'
}
})
.then(res => console.log(res.data))
.catch(err => console.error(err));
POST 요청 및 데이터 전송
서버로 새로운 리소스를 생성하거나 데이터를 전송할 때는 POST 메서드를 사용합니다. 두 번째 인자로 전송할 페이로드(payload)를 전달합니다.
const payload = {
username: 'dev_user',
email: 'dev@example.com',
preferences: { theme: 'dark' }
};
axios.post('https://api.example.com/v1/users/register', payload)
.then(res => {
console.log('등록 성공:', res.data.userId);
})
.catch(err => {
console.error('등록 실패:', err.response?.data?.message);
});
다중 요청 병렬 처리
여러 개의 독립적인 API를 동시에 호출해야 할 경우, Promise.all을 사용하여 네트워크 대기 시간을 단축할 수 있습니다. (참고: 기존 axios.all는 공식적으로 지원이 중단되었으므로 표준 Promise.all 사용을 권장합니다.)
const fetchUserProfile = () => axios.get('https://api.example.com/v1/users/1001');
const fetchUserActivity = () => axios.get('https://api.example.com/v1/users/1001/activity');
Promise.all([fetchUserProfile(), fetchUserActivity()])
.then(([profileRes, activityRes]) => {
console.log('프로필:', profileRes.data);
console.log('활동 내역:', activityRes.data);
})
.catch(err => console.error('병렬 요청 실패:', err));
Axios 인스턴스 및 커스텀 설정
매 요청마다 동일한 설정을 반복하는 것을 피하기 위해, 커스텀 설정이 적용된 Axios 인스턴스를 생성하여 재사용할 수 있습니다.
const apiClient = axios.create({
baseURL: 'https://api.example.com/v2/',
timeout: 5000,
headers: {
'X-Custom-Header': 'VueApp',
'Accept': 'application/json'
}
});
// 인스턴스를 통한 요청
apiClient.get('/metrics')
.then(res => console.log(res.data));
주요 요청 설정 옵션 (Request Config)
요청을 생성할 때 전달할 수 있는 주요 설정 객체의 구조입니다.
{
url: '/endpoint', // 필수: 요청할 서버의 엔드포인트
method: 'get', // HTTP 메서드 (기본값: get)
baseURL: 'https://api.example.com', // 상대 경로 URL 사용 시 자동 결합
headers: { 'Authorization': 'Bearer token_value' }, // 커스텀 헤더
params: { search: 'keyword' }, // URL 쿼리 파라미터
data: { key: 'value' }, // 요청 본문 (POST, PUT, PATCH 전용)
timeout: 3000, // 요청 타임아웃 (밀리초)
withCredentials: true, // CORS 요청 시 쿠키 및 인증 정보 포함 여부
responseType: 'json', // 응답 데이터 타입 (arraybuffer, blob, text 등)
validateStatus: function (status) {
return status >= 200 && status < 300; // Promise를 resolve할 HTTP 상태 코드 범위
}
}
응답 객체 구조 (Response Schema)
요청이 성공적으로 완료되면 Axios는 다음과 같은 구조의 응답 객체를 반환합니다.
{
data: {}, // 서버에서 반환된 실제 페이로드
status: 200, // HTTP 상태 코드
statusText: 'OK', // HTTP 상태 메시지
headers: {}, // 서버 응답 헤더
config: {} // 해당 요청에 사용된 Axios 설정 객체
}
인터셉터(Interceptors)를 활용한 전역 처리
인터셉터를 사용하면 요청이 전송되기 전이나 응답을 받은 직후에 특정 로직(예: 토큰 주입, 전역 에러 로깅)을 가로채어 실행할 수 있습니다.
// 요청 인터셉터: 인증 토큰 자동 주입
const reqInterceptor = apiClient.interceptors.request.use(
config => {
const token = localStorage.getItem('auth_token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
error => Promise.reject(error)
);
// 응답 인터셉터: 전역 에러 핸들링
apiClient.interceptors.response.use(
response => response,
error => {
if (error.response && error.response.status === 401) {
console.warn('인증이 만료되었습니다. 로그인 페이지로 이동합니다.');
// 리디렉션 로직 수행
}
return Promise.reject(error);
}
);
// 인터셉터 해제
apiClient.interceptors.request.eject(reqInterceptor);
요청 취소 (Cancellation)
사용자가 페이지를 이탈하거나 특정 조건에 의해 진행 중인 네트워크 요청을 중단해야 할 때, 최신 웹 표준인 AbortController를 사용하는 것이 권장됩니다.
const controller = new AbortController();
axios.get('https://api.example.com/v1/large-dataset', {
signal: controller.signal
})
.then(res => console.log('데이터 로드 완료'))
.catch(err => {
if (axios.isCancel(err)) {
console.log('사용자에 의해 요청이 취소됨:', err.message);
} else {
console.error('기타 네트워크 오류:', err);
}
});
// 특정 시점에 요청 중단
setTimeout(() => {
controller.abort('더 이상 데이터가 필요하지 않음');
}, 1000);
Form URL Encoded 형식 전송
Axios는 기본적으로 JavaScript 객체를 JSON으로 직렬화하여 전송합니다. 만약 application/x-www-form-urlencoded 형식으로 데이터를 보내야 한다면, 환경에 맞는 직렬화 도구를 사용해야 합니다.
브라우저 환경 (URLSearchParams)
const formData = new URLSearchParams();
formData.append('clientId', 'web_app');
formData.append('grantType', 'authorization_code');
axios.post('https://api.example.com/oauth/token', formData, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
});
Node.js 환경 (qs 라이브러리)
const qs = require('qs');
const payload = { filter: { status: 'active' }, sort: 'created_at' };
axios.post('https://api.example.com/v1/search', qs.stringify(payload), {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
});
TypeScript 지원
Axios는 내장된 TypeScript 타입 정의를 제공하여, 개발 시 안정적인 타입 추론과 자동 완성을 지원합니다.
import axios, { AxiosResponse } from 'axios';
interface User {
id: number;
name: string;
}
axios.get<User>('https://api.example.com/v1/users/1')
.then((response: AxiosResponse<User>) => {
console.log(response.data.name); // 타입 안전성 보장
});