The built-in
fetch() is the basic radio transmitter of our spaceship. But what if we need an advanced communication system with automatic filters, retransmissions, and a configurable command center? That's when we reach for Axios -- the most popular HTTP library for JavaScript.Fetch is great for simple requests, but Axios offers many conveniences:
1// FETCH - requires manual handling
2const response = await fetch(url);
3if (!response.ok) throw new Error('Error'); // fetch does NOT throw errors for 4xx/5xx!
4const data = await response.json(); // must manually parse JSON
5
6// AXIOS - simpler and safer
7const { data } = await axios.get(url); // automatic JSON, throws errors for 4xx/5xxKey differences:
| Feature | fetch() | Axios | |-------|---------|-------| | JSON Parsing | Manual (
.json()) | Automatic |
| HTTP Errors | Doesn't throw for 4xx/5xx | Throws automatically |
| Interceptors | None | Built-in |
| Timeout | No built-in | Built-in |
| Cancellation | AbortController | CancelToken + AbortController |
| Transformation | Manual | Built-in |1// Installation: npm install axios
2
3import axios from 'axios';
4
5// GET - fetching data
6const response = await axios.get(
7 'https://api.space-center.com/planets'
8);
9console.log(response.data); // data (already parsed!)
10console.log(response.status); // 200
11console.log(response.headers); // headers
12
13// POST - sending data (automatic JSON serialization)
14const newMission = await axios.post(
15 'https://api.space-center.com/missions',
16 { name: 'Alpha Centauri', crew: 5 }
17);
18
19// PUT, DELETE
20await axios.put(url, updatedData);
21await axios.delete(url);Instead of providing the base URL every time, we create a configured instance:
1// Create an API client with default configuration
2const spaceApi = axios.create({
3 baseURL: 'https://api.space-center.com',
4 timeout: 10000, // 10 seconds
5 headers: {
6 'Content-Type': 'application/json',
7 'X-Station-Id': 'ISS-2150',
8 },
9});
10
11// Now we use shorter paths
12const planets = await spaceApi.get('/planets');
13const missions = await spaceApi.get('/missions');
14const newMission = await spaceApi.post('/missions', {
15 name: 'Deep Space Survey',
16 destination: 'Proxima Centauri',
17});Interceptors are "filters" on our communication channel. They intercept every request or response:
1// Request interceptor - adds authorization token
2spaceApi.interceptors.request.use(config => {
3 const token = localStorage.getItem('authToken');
4 if (token) {
5 config.headers.Authorization = \`Bearer \${token}\`;
6 }
7 console.log('Sending request:', config.url);
8 return config;
9});
10
11// Response interceptor - error handling
12spaceApi.interceptors.response.use(
13 response => {
14 // Success - return data
15 return response;
16 },
17 error => {
18 // Error - handle globally
19 if (error.response?.status === 401) {
20 console.log('Session expired - redirecting to login');
21 window.location.href = '/login';
22 }
23 if (error.response?.status === 429) {
24 console.log('Too many requests - try again later');
25 }
26 return Promise.reject(error);
27 }
28);Axios allows you to transform data before sending and after receiving:
1const api = axios.create({
2 baseURL: 'https://api.space-center.com',
3 // Transform before sending
4 transformRequest: [(data) => {
5 // Add timestamp to every request
6 return JSON.stringify({
7 ...data,
8 timestamp: Date.now(),
9 source: 'space-station',
10 });
11 }],
12 // Transform after receiving
13 transformResponse: [(data) => {
14 const parsed = JSON.parse(data);
15 // Add "fetchedAt" field to every response
16 return { ...parsed, fetchedAt: new Date().toISOString() };
17 }],
18});Axios automatically throws errors for HTTP codes 4xx and 5xx:
1async function fetchPlanet(id) {
2 try {
3 const { data } = await spaceApi.get(
4 \`/planets/\${id}\`
5 );
6 return data;
7 } catch (error) {
8 if (error.response) {
9 // Server responded with error code (4xx, 5xx)
10 console.error('Status:', error.response.status);
11 console.error('Data:', error.response.data);
12 } else if (error.request) {
13 // Request sent, but no response (timeout, network)
14 console.error('No response from server');
15 } else {
16 // Error in request configuration
17 console.error('Configuration error:', error.message);
18 }
19 throw error;
20 }
21}1import React, { useState, useEffect } from 'react';
2import axios from 'axios';
3
4const spaceApi = axios.create({
5 baseURL: 'https://swapi.dev/api',
6 timeout: 8000,
7});
8
9function CrewList() {
10 const [crew, setCrew] = useState([]);
11 const [loading, setLoading] = useState(true);
12 const [error, setError] = useState(null);
13
14 useEffect(() => {
15 const source = axios.CancelToken.source();
16
17 async function loadCrew() {
18 try {
19 const { data } = await spaceApi.get('/people/', {
20 cancelToken: source.token,
21 });
22 setCrew(data.results);
23 } catch (err) {
24 if (!axios.isCancel(err)) {
25 setError(err.message);
26 }
27 } finally {
28 setLoading(false);
29 }
30 }
31
32 loadCrew();
33 return () => source.cancel('Component unmounted');
34 }, []);
35
36 if (loading) return <p>Scanning crew roster...</p>;
37 if (error) return <p>Error: {error}</p>;
38
39 return (
40 <ul>
41 {crew.map(member => (
42 <li key={member.name}>{member.name}</li>
43 ))}
44 </ul>
45 );
46}Axios is like an advanced communication system on the bridge -- it gives you full control over every request, automatically handles errors, and lets you centrally manage the configuration of your entire fleet!