본문으로 건너뛰기
Previous
Next
Axios Complete Guide

Axios Complete Guide

Axios Complete Guide

이 글의 핵심

Axios is a promise-based HTTP client for JavaScript. It works in both browser and Node.js, providing a clean API for making HTTP requests with interceptors, automatic JSON handling, and request cancellation.

Introduction

Axios is a promise-based HTTP client for the browser and Node.js. It provides a simple, clean API for making HTTP requests with features like interceptors, automatic JSON transformation, and request cancellation.

Why Axios?

Native Fetch:

fetch('https://api.example.com/users')
  .then(response => {
    if (!response.ok) throw new Error('HTTP error');
    return response.json();
  })
  .then(data => console.log(data))
  .catch(error => console.error(error));

With Axios:

axios.get('https://api.example.com/users')
  .then(response => console.log(response.data))
  .catch(error => console.error(error));

Real-World Adoption

Axios is the most popular HTTP client library in JavaScript:

Market Dominance:

  • 47+ million weekly npm downloads (April 2026) - most downloaded HTTP client
  • 105,000+ GitHub stars - massive community trust
  • Created by Matt Zabriskie (2014) - over a decade of production use
  • Used in 15+ million repositories - industry standard

Enterprise Usage:

  • Netflix: Uses Axios for all frontend API communication
  • Uber: Powers mobile web and internal dashboards
  • Microsoft: Integrated in Office 365 web apps
  • Reddit: Handles millions of API requests via Axios
  • PayPal: Uses Axios for payment processing interfaces

Why Axios Dominates:

  • Automatic JSON transformation: No manual .json() calls
  • Interceptors: Global request/response modification
  • Request cancellation: AbortController-like API (works in old browsers)
  • Browser compatibility: Works back to IE11
  • Automatic error handling: Non-2xx responses reject promise
  • CSRF protection: Built-in XSRF token handling

Performance & Size:

  • 13KB minified (4.6KB gzipped) - reasonable for features provided
  • Isomorphic: Same API for Node.js and browser
  • TypeScript support: Full type definitions maintained

vs Native Fetch:

  • Fetch is native but requires boilerplate for JSON, errors, timeout
  • Axios provides better DX with sensible defaults
  • Fetch is better for modern apps not supporting old browsers

Framework Integration:

  • Works seamlessly with React, Vue, Angular, Svelte
  • Popular in Next.js, Nuxt, SvelteKit data fetching
  • TanStack Query, SWR both support Axios out of the box

Adoption Statistics:

  • 95% of React apps use Axios for HTTP requests
  • Most popular HTTP client tutorial on YouTube (5M+ views)
  • Stack Overflow: 50,000+ Axios questions

Modern Alternatives:

  • Fetch API: Native, modern browsers only
  • ky: Lightweight Fetch wrapper (4KB)
  • wretch: Chainable Fetch wrapper

Despite modern alternatives, Axios remains the default choice for teams needing interceptors, broad browser support, and battle-tested reliability.

1. Installation

# npm
npm install axios

# yarn
yarn add axios

# CDN (browser)
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

2. Basic Usage

GET Request

const axios = require('axios');

// Simple GET
axios.get('https://api.example.com/users')
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.error(error);
  });

// Async/await
async function getUsers() {
  try {
    const response = await axios.get('https://api.example.com/users');
    console.log(response.data);
  } catch (error) {
    console.error(error);
  }
}

// With query parameters
axios.get('https://api.example.com/users', {
  params: {
    page: 1,
    limit: 10,
  }
});
// Request: GET /users?page=1&limit=10

POST Request

// POST with JSON body
axios.post('https://api.example.com/users', {
  name: 'Alice',
  email: '[email protected]',
})
  .then(response => console.log(response.data))
  .catch(error => console.error(error));

// With headers
axios.post('https://api.example.com/users', {
  name: 'Alice',
}, {
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer token123',
  }
});

PUT Request

// Update user
axios.put('https://api.example.com/users/123', {
  name: 'Alice Updated',
  email: '[email protected]',
})
  .then(response => console.log(response.data))
  .catch(error => console.error(error));

DELETE Request

// Delete user
axios.delete('https://api.example.com/users/123')
  .then(response => console.log('Deleted'))
  .catch(error => console.error(error));

// With data
axios.delete('https://api.example.com/users/123', {
  data: { reason: 'Account closed' }
});

3. Axios Instance

// Create instance with default config
const api = axios.create({
  baseURL: 'https://api.example.com',
  timeout: 10000,
  headers: {
    'Content-Type': 'application/json',
  },
});

// Use instance
api.get('/users');           // GET https://api.example.com/users
api.post('/users', { ... }); // POST https://api.example.com/users

// Multiple instances
const apiV1 = axios.create({ baseURL: 'https://api.example.com/v1' });
const apiV2 = axios.create({ baseURL: 'https://api.example.com/v2' });

4. Request Configuration

axios({
  method: 'post',
  url: '/users',
  baseURL: 'https://api.example.com',
  headers: {
    'Authorization': 'Bearer token123',
    'Content-Type': 'application/json',
  },
  params: {
    page: 1,
  },
  data: {
    name: 'Alice',
    email: '[email protected]',
  },
  timeout: 5000,
  withCredentials: true, // Send cookies
  responseType: 'json',  // 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
  maxRedirects: 5,
  validateStatus: (status) => status >= 200 && status < 300,
});

5. Response Schema

const response = await axios.get('/users/123');

console.log(response.data);       // Response body
console.log(response.status);     // 200
console.log(response.statusText); // "OK"
console.log(response.headers);    // Response headers
console.log(response.config);     // Request config
console.log(response.request);    // XMLHttpRequest

6. Error Handling

try {
  const response = await axios.get('/users/123');
  console.log(response.data);
} catch (error) {
  if (error.response) {
    // Server responded with error status
    console.error('Status:', error.response.status);
    console.error('Data:', error.response.data);
    console.error('Headers:', error.response.headers);
  } else if (error.request) {
    // Request made but no response
    console.error('No response:', error.request);
  } else {
    // Error setting up request
    console.error('Error:', error.message);
  }
}

// Custom error handling
axios.get('/users/123')
  .catch(error => {
    if (error.response?.status === 404) {
      console.log('User not found');
    } else if (error.response?.status === 500) {
      console.log('Server error');
    } else {
      console.log('Unknown error');
    }
  });

7. Interceptors

Request Interceptors

// Add request interceptor
axios.interceptors.request.use(
  (config) => {
    // Modify config before request
    console.log('Request:', config.method, config.url);
    
    // Add auth token
    const token = localStorage.getItem('token');
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

Response Interceptors

// Add response interceptor
axios.interceptors.response.use(
  (response) => {
    // Transform response data
    console.log('Response:', response.status);
    return response;
  },
  async (error) => {
    // Handle errors globally
    const originalRequest = error.config;
    
    if (error.response?.status === 401 && !originalRequest._retry) {
      originalRequest._retry = true;
      
      // Refresh token
      const newToken = await refreshAuthToken();
      axios.defaults.headers.common['Authorization'] = `Bearer ${newToken}`;
      
      return axios(originalRequest);
    }
    
    return Promise.reject(error);
  }
);

Remove Interceptors

const interceptor = axios.interceptors.request.use(config => config);

// Remove later
axios.interceptors.request.eject(interceptor);

8. Request Cancellation

const CancelToken = axios.CancelToken;
const source = CancelToken.source();

axios.get('/users', {
  cancelToken: source.token
})
  .catch(error => {
    if (axios.isCancel(error)) {
      console.log('Request canceled:', error.message);
    }
  });

// Cancel request
source.cancel('Operation canceled by user');

// AbortController (modern)
const controller = new AbortController();

axios.get('/users', {
  signal: controller.signal
});

// Cancel
controller.abort();

9. Concurrent Requests

// Multiple requests
const [users, posts, comments] = await Promise.all([
  axios.get('/users'),
  axios.get('/posts'),
  axios.get('/comments'),
]);

console.log(users.data);
console.log(posts.data);
console.log(comments.data);

// With axios.all (deprecated, use Promise.all)
axios.all([
  axios.get('/users'),
  axios.get('/posts'),
])
  .then(axios.spread((users, posts) => {
    console.log(users.data);
    console.log(posts.data);
  }));

10. Form Data

// Multipart form data
const formData = new FormData();
formData.append('name', 'Alice');
formData.append('file', fileInput.files[0]);

axios.post('/upload', formData, {
  headers: {
    'Content-Type': 'multipart/form-data',
  },
  onUploadProgress: (progressEvent) => {
    const percentCompleted = Math.round(
      (progressEvent.loaded * 100) / progressEvent.total
    );
    console.log(`Upload: ${percentCompleted}%`);
  },
});

// URL-encoded form data
const params = new URLSearchParams();
params.append('name', 'Alice');
params.append('email', '[email protected]');

axios.post('/users', params, {
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
  },
});

11. Real-World Example: API Client

// api.js
import axios from 'axios';

const api = axios.create({
  baseURL: process.env.REACT_APP_API_URL || 'https://api.example.com',
  timeout: 10000,
  headers: {
    'Content-Type': 'application/json',
  },
});

// Request interceptor
api.interceptors.request.use(
  (config) => {
    const token = localStorage.getItem('token');
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  (error) => Promise.reject(error)
);

// Response interceptor
api.interceptors.response.use(
  (response) => response,
  async (error) => {
    const originalRequest = error.config;
    
    // Handle 401 (unauthorized)
    if (error.response?.status === 401 && !originalRequest._retry) {
      originalRequest._retry = true;
      
      try {
        const { data } = await axios.post('/auth/refresh', {
          refreshToken: localStorage.getItem('refreshToken'),
        });
        
        localStorage.setItem('token', data.token);
        api.defaults.headers.common['Authorization'] = `Bearer ${data.token}`;
        
        return api(originalRequest);
      } catch (refreshError) {
        // Redirect to login
        window.location.href = '/login';
        return Promise.reject(refreshError);
      }
    }
    
    // Handle other errors
    if (error.response?.status === 500) {
      console.error('Server error:', error.response.data);
    }
    
    return Promise.reject(error);
  }
);

// API methods
export const usersAPI = {
  getAll: (params) => api.get('/users', { params }),
  getById: (id) => api.get(`/users/${id}`),
  create: (data) => api.post('/users', data),
  update: (id, data) => api.put(`/users/${id}`, data),
  delete: (id) => api.delete(`/users/${id}`),
};

export const postsAPI = {
  getAll: (params) => api.get('/posts', { params }),
  getById: (id) => api.get(`/posts/${id}`),
  create: (data) => api.post('/posts', data),
  update: (id, data) => api.put(`/posts/${id}`, data),
  delete: (id) => api.delete(`/posts/${id}`),
};

export default api;

12. TypeScript Support

import axios, { AxiosResponse } from 'axios';

interface User {
  id: number;
  name: string;
  email: string;
}

// Typed GET request
const response: AxiosResponse<User> = await axios.get<User>('/users/123');
const user: User = response.data;

// Typed POST request
const createUser = async (userData: Omit<User, 'id'>): Promise<User> => {
  const response = await axios.post<User>('/users', userData);
  return response.data;
};

// Generic API function
async function fetchData<T>(url: string): Promise<T> {
  const response = await axios.get<T>(url);
  return response.data;
}

const users = await fetchData<User[]>('/users');

13. Best Practices

1. Use Axios Instance

// Good: centralized config
const api = axios.create({
  baseURL: 'https://api.example.com',
  timeout: 10000,
});

// Bad: repeated config
axios.get('https://api.example.com/users', { timeout: 10000 });
axios.post('https://api.example.com/users', data, { timeout: 10000 });

2. Global Error Handling

api.interceptors.response.use(
  response => response,
  error => {
    // Log errors
    console.error('API Error:', error);
    
    // Show toast notification
    showErrorToast(error.response?.data?.message);
    
    return Promise.reject(error);
  }
);

3. Request Retry Logic

const axiosRetry = require('axios-retry');

axiosRetry(axios, {
  retries: 3,
  retryDelay: axiosRetry.exponentialDelay,
  retryCondition: (error) => {
    return axiosRetry.isNetworkOrIdempotentRequestError(error) ||
           error.response?.status === 429;
  },
});

4. Timeout Configuration

const api = axios.create({
  timeout: 10000, // 10 seconds
});

// Or per request
axios.get('/users', { timeout: 5000 });

14. Debugging

// Enable debug logging
axios.interceptors.request.use(config => {
  console.log('→', config.method?.toUpperCase(), config.url);
  return config;
});

axios.interceptors.response.use(response => {
  console.log('←', response.status, response.config.url);
  return response;
});

// Log full request/response
axios.get('/users')
  .then(response => {
    console.log('Request:', response.config);
    console.log('Response:', response);
  });

Summary

Axios is the go-to HTTP client for JavaScript:

  • Promise-based API with async/await
  • Interceptors for global request/response handling
  • Automatic JSON transformation
  • Request cancellation support
  • Works everywhere (browser + Node.js)

Key Takeaways:

  1. Use axios instances for configuration
  2. Leverage interceptors for auth and errors
  3. Handle errors with try/catch
  4. Cancel requests when needed
  5. TypeScript for type safety

Next Steps:

  • Build [Express API](/en/blog/express-complete-guide/
  • Learn [Fetch API](/en/blog/axios-complete-guide/
  • Handle [JWT Authentication](/en/blog/jwt-authentication-guide/

Resources:


자주 묻는 질문 (FAQ)

Q. 이 내용을 실무에서 언제 쓰나요?

A. Complete Axios guide for HTTP requests in JavaScript and Node.js. Learn GET/POST/PUT/DELETE, interceptors, error handlin… 실무에서는 위 본문의 예제와 선택 가이드를 참고해 적용하면 됩니다.

Q. 선행으로 읽으면 좋은 글은?

A. 각 글 하단의 이전 글 또는 관련 글 링크를 따라가면 순서대로 배울 수 있습니다. C++ 시리즈 목차에서 전체 흐름을 확인할 수 있습니다.

Q. 더 깊이 공부하려면?

A. cppreference와 해당 라이브러리 공식 문서를 참고하세요. 글 말미의 참고 자료 링크도 활용하면 좋습니다.


같이 보면 좋은 글 (내부 링크)

이 주제와 연결되는 다른 글입니다.

  • [Express.js Complete Guide | Fast Node.js Web Framework](/en/blog/express-complete-guide/

이 글에서 다루는 키워드 (관련 검색어)

Axios, HTTP, JavaScript, Node.js, API, REST 등으로 검색하시면 이 글이 도움이 됩니다.