Axios vs. Fetch API: Selecting the Right Tool for HTTP Requests

20 Vintage Color Palettes
20 Vintage Color Palettes for Kickin’ it Old School
29th July 2024
watch os
Apple watchOS (Apple Watch operating system)
9th August 2024
20 Vintage Color Palettes
20 Vintage Color Palettes for Kickin’ it Old School
29th July 2024
watch os
Apple watchOS (Apple Watch operating system)
9th August 2024

Axios vs. Fetch API know the key difference : In the field of software development, the ability to seamlessly interact with remote servers and exchange data over the web is very important. Whether it’s fetching data from an API, performing CRUD operations, or executing any other network-related task, the significance of making HTTP requests cannot be overstated. Two widely used JavaScript libraries, Fetch and Axios, have become top picks for developers seeking to handle HTTP requests. Axios and Fetch to see how they can be used to perform different tasks. Hopefully, by the end of the article, you’ll have a better understanding of both APIs

fetch/axios

AXIOS

Axios is a third-party HTTP client library for making network requests. It is promise-based and provides a clean and consistent API for handling requests and responses.

You can add it to your project via a content distribution network (CDN) or by using a package manager (like npm). Some of its core features include: making XMLHttpRequests within a browser, making http requests within a node.js environment, canceling requests, and intercepting request and response.

FETCH

Fetch, like Axios, is a promise-based HTTP client. It is a built-in API; hence we don’t have to install or import anything. It’s available in all modern browsers; you can check it on caniuse. Fetch is also available in node.js — you can read more about it here.

Let’s now compare their basic syntax, features, and use cases as we try to understand the two popularly used libraries.

Basic Syntax

Axios simplifies HTTP requests with a chainable API which allows for straightforward configuration of request parameters, such as headers, data, and request method.

Here’s how to use Axios to send a [POST] request with custom headers to a URL. Axios automatically converts the data to JSON, so you don’t have to.

const axios = require('axios');

const url = 'https://jsonplaceholder.typicode.com/posts';
const data = {
title: 'Hello World',
body: 'This is a test post.',
userId: 1,
};

axios
.post(url, data, {
headers: {
Accept: 'application/json',
'Content-Type': 'application/json;charset=UTF-8',
},
})
.then(({ data }) => {
console.log("POST request successful. Response:", data);
})
.catch(error => {
console.error('Error:', error);
});

Compare that code to the fetch API code, which produces the exact same result:

const url = "https://jsonplaceholder.typicode.com/todos";

const options = {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json;charset=UTF-8",
},
body: JSON.stringify({
title: "Hello World",
body: "This is a test post.",
userId: 1,
}),
};

fetch(url, options)
.then((response) => response.json())
.then((data) => {
console.log("POST request successful. Response:", data);
});

Fetch uses the body property for sending data in a POST request, whereas Axios utilizes the data property. Axios will automatically transforms the server’s response data, while with Fetch, you need to call the response.json method to parse the data into a JavaScript object. Furthermore, Axios delivers the data response within the data object, whereas Fetch allows the final data to be stored in any variable.

Handling Response and Errors

Fetch offers precise control over the loading process but introduces complexity by requiring the handling of two promises. Additionally, when dealing with responses, Fetch requires parsing JSON data using the .json() method. The final data retrieved can then be stored in any variable.

For HTTP response errors, Fetch does not automatically throw an error. Instead, it considers the response as successful even if the server returns an error status code (e.g., 404 Not found).

To handle HTTP errors explicitly in Fetch, developers have to use conditional statements within the .then() block to check the response.ok property. If response.ok is false, it indicates that the server responded with an error status code, and developers can handle the error accordingly.

Here is a [GET] request using fetch:

fetch('https://jsonplaceholder.typicode.com/todos')
.then(response => {
if (!response.ok) {
throw Error(`HTTP error: ${response.status}`);
}
return response.json();
})
.then(data => {
console.log('Data received:', data);
})
.catch(error => {
console.error('Error message:', error.message);
});

Axios, on the other hand, simplifies response handling by directly providing access to the data property. It automatically rejects responses outside of the 200–299 range (successful responses). By utilizing a .catch() block, information about the error can be obtained, including whether a response was received and, if so, its status code. This contrasts with fetch, where unsuccessful responses are still resolved.

Here is a [GET] request using Axios:

const axios = require("axios");

axios
.get("https://jsonplaceholder.typicode.com/todos")
.then((response) => {
console.log("Data received:", response.data);
})
.catch((error) => {
if (error.response) {
console.error(`HTTP error: ${error.response.status}`);
} else if (error.request) {
console.error("Request error: No response received");
} else {
console.error("Error:", error.message);
}
});

By automatically throwing errors for unsuccessful responses, Axios simplifies error handling and allows developers to focus on implementing appropriate error-handling logic without having to manually check each response for success or failure.

Intercepting HTTP Requests and Responses

One of the key features of Axios is its ability to intercept HTTP requests. HTTP interceptors come in handy when you need to examine or change HTTP requests from your application to the server or vice versa. This functionality is essential for various tasks such as logging, authentication, or retrying failed HTTP requests.

With interceptors, you won’t have to write separate code for each HTTP request. HTTP interceptors are helpful when you want to set a global strategy for how you handle requests and responses.

Here is how to intercept an HTTP request using Axios:

const axios = require("axios");

// Register a request interceptor
axios.interceptors.request.use((config) => {
// Log a message before any HTTP request is sent
console.log("Request was sent");
return config;
});

// Send a GET request
axios
.get("https://jsonplaceholder.typicode.com/todos")
.then(({data}) => {
console.log("Data received:", data);
})
.catch((error) => {
console.error("Error:", error.message);
});

In this code, the axios.interceptors.request.use() method is used to define code to run before an HTTP request is sent.

Additionally, axios.interceptors.request.use() can be employed to intercept the response from the server. For instance, in the event of a network error, response interceptors can be utilized to retry the same request using interceptors.

By default, fetch() doesn’t provide a way to intercept requests, but it’s not hard to come up with a workaround. You can overwrite the global fetch() method and define your interceptor, like this:

Here is how to intercept an HTTP request using Fetch:

fetch = ((originalFetch) => {
return (...arguments) => {
return originalFetch.apply(this, arguments).then((response) => {
if (!response.ok) {
throw new Error(`HTTP error: ${response.status}`);
}
console.log("Request was sent");
return response;
});
};
})(fetch);

fetch("https://jsonplaceholder.typicode.com/todos")
.then((response) => response.json())
.then((data) => {
console.log("Data received:", data);
})
.catch((error) => {
console.error("Error:", error.message);
});

Fetch tends to have more boilerplate code compared to Axios. However, the choice should be based on the use case and individual needs.

Response Timeout

Response timeout is indeed another important area for comparison between Fetch and Axios. Response timeout refers to the duration for which a client will wait for a response from the server before considering the request as failed.

The simplicity of setting a timeout in Axios is one of the reasons some developers prefer it to Fetch. In Axios, you can use the optional timeout property in the config object to set the number of milliseconds before the request is aborted. This straightforward approach allows developers to define the timeout duration directly within the request configuration, providing greater control and ease of implementation.

Here is a [GET] request with a specified timeout using Axios:

const axios = require('axios');

// Define the timeout duration in milliseconds
const timeout = 5000; // 5 seconds

// Create a config object with the timeout property
const config = {
timeout: timeout
};

// Send a GET request with the specified timeout
axios.get('https://jsonplaceholder.typicode.com/todos', config)
.then(response => {
console.log('Data received:', response.data);
})
.catch(error => {
console.error('Error fetching data:', error.message);
});

A GET request is being sent using Axios, passing the config object as the second argument to specify the timeout. If the request is successful, the received data is logged to the console. If an error occurs during the request or if the timeout is reached, the error message is logged to the console.

Fetch offers similar functionality through the AbortController interface, although it’s not as straightforward as the Axios version.

Here is how to intercept an HTTP request using Fetch:

const timeout = 5000; // 5 seconds
// Create an AbortController instance
const controller = new AbortController();
const signal = controller.signal;

// Set up a setTimeout function to abort the fetch request after the specified timeout
const timeoutId = setTimeout(() => {
controller.abort();
}, timeout);

// Make the fetch request with the specified URL and signal
fetch('https://jsonplaceholder.typicode.com/todos', { signal })
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
console.log('Data received:', data);
})
.catch(error => {
// Check if the error is due to the request being aborted
if (error.name === 'AbortError') {
console.error('Request timed out');
} else {
console.error('Error fetching data:', error.message);
}
})
.finally(() => {
// Clear the timeout to prevent it from firing after the request has completed
clearTimeout(timeoutId);
});

A 5-second timeout is set for the fetch request, and an AbortController is created to cancel it if it exceeds this limit. Using setTimeout, a timer is initiated to abort the request after this duration. Then, the fetch request is sent, including the abort signal. Upon response, it checks for success and parses the data. Any errors, such as timeouts, are managed accordingly. Finally, the timeout is cleared to avoid unnecessary delays after the request finished.

Simultaneous requests

Simultaneous requests, or the ability to make multiple requests concurrently, is another crucial aspect for comparison between Fetch and Axios. This feature is particularly important in applications where performance and responsiveness are paramount.

To make multiple simultaneous requests, Axios provides the 
axios.all()
 method. Simply pass an array of requests to this method, then use axios.spread()to spread the responses into separate arguments. This allows handling of each response individually.

Here is how to send simultaneous HTTP requests using Axios:

const axios = require('axios');

// Define the base URL for the request
const baseURL = 'https://jsonplaceholder.typicode.com/todos';

// Define the URLs for the requests
const urls = [
`${baseURL}/1`,
`${baseURL}/2`,
`${baseURL}/3`
];

// Create an array of Axios request promises
const axiosRequests = urls.map(url => axios.get(url));

// Send multiple requests simultaneously using `axios.all()`
axios.all(axiosRequests)
.then(axios.spread((...responses) => {
// Handle responses from all requests
responses.forEach((response, index) => {
console.log(`Response from ${urls[index]}:`, response.data);
});
}))
.catch(error => {
console.error('Error fetching data:', error.message);
});

To achieve the same result using Fetch we have to rely on the built-in Promise.all()method. Pass all fetch requests as an array to Promise.all(). Next, handle the response by using an async function.

Here is how to send simultaneous HTTP requests using Fetch:

// Define the base URL for the requests
const baseURL = "https://jsonplaceholder.typicode.com/todos";

// Define the URLs for the requests
const urls = [`${baseURL}/1`, `${baseURL}/2`, `${baseURL}/3`];

// Create an array to store the fetch request promises
const fetchRequests = urls.map((url) => fetch(url));

// Send multiple requests simultaneously using `Promise.all()`
Promise.all(fetchRequests)
.then((responses) => {
// Handle responses from all requests
responses.forEach((response, index) => {
if (!response.ok) {
throw new Error(
`Request ${urls[index]} failed with status ${response.status}`
);
}
response.json().then((data) => {
console.log(`Response from ${urls[index]}:`, data);
});
});
})
.catch((error) => {
console.error("Error fetching data:", error.message);
});

While this approach is feasible, it may introduce additional complexity and overhead, especially for developers unfamiliar with asynchronous programming concepts.

Conclusion

Axios stands out for its simplicity, robustness, and extensive browser support, making it an ideal choice for projects requiring backward compatibility with older browsers. On the other hand, Fetch offers a more native approach, built directly into the browser, with support for features like streaming and the ability to work with other web platform APIs seamlessly.

When making a decision between Axios and Fetch, developers should carefully evaluate their project requirements, including factors such as ease of use, performance considerations, browser compatibility and additional features needed.

read more about: FETCH VS AXIOS

more info: xpertlab