본문으로 건너뛰기 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: 'alice@example.com',
})
  .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: 'alice-new@example.com',
})
  .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: 'alice@example.com',
  },
  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', 'alice@example.com');

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:

Resources:


Frequently Asked Questions (FAQ)

Q. When would I use this in practice?

A. Complete Axios guide for HTTP requests in JavaScript and Node.js.

Q. What should I read before this?

A. Follow the previous article or related articles links at the bottom of each post to learn in sequence.

Q. Where can I study this more deeply?

A. Check cppreference and the relevant library’s official documentation. The reference links at the end of the article are also worth using.


Other articles related to this topic.


Keywords Covered in This Article (Related Search Terms)

This article covers Axios, HTTP, JavaScript, Node.js, API, REST.