Axios vs Fetch: Which HTTP Client Should You Use in 2024?

Axios vs Fetch: Which HTTP Client Should You Use in 2024?

In web development, fetching data from a remote server is crucial as it helps to access dynamic data, reduce memory, and optimize the performance of an application. Rather than store big chunks of static data locally, it is stored on a remote server which provides the data on request.

HTTP requests control how an application handles data from a server, including actions like fetching data from an API, loading user information, and other related network requests. Axios and Fetch are two popular tools developers use to handle HTTP requests in JavaScript. Developers need to know about Axios and Fetch, how to use them, and which one to use in your project.

In this blog post, we’ll discuss Axios vs Fetch, their features, and the differences between them, helping you choose the right HTTP client for your application.

Axios

Axios is a promise-based third-party HTTP client library for making requests to a remote server. It works on both the client side (in the browser) and the server side (Node.js). Axios provides an easy-to-use API that helps facilitate communication between an application and the server by sending requests and receiving responses. It also can cancel requests.

Key features of Axios include:

  • It supports the Promise API and seamlessly handles asynchronous code.

  • It makes HTTP requests from Node.js and XMLHttpRequests from the browser.

  • It supports API methods like GET, POST, PUT, DELETE, and PATCH.

  • It supports a variety of actions on requests and responses such as interception, transformation of data, and cancellation.

  • It allows you to set a timeout to prevent waiting indefinitely for a request to complete.

Installation

You can install Axios from NPM by running the command below:

npm install axios

You can alternatively use the jsDelivr CDN:

<script src="cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

Syntax

The syntax of Axios is fairly straightforward; it allows easy configuration of the request parameters such as the header and data. Here’s the basic syntax for sending a POST request in Axios:

const axios = require('axios')
axios.get('api.mockendpoint.com/data')
  .then(response => {
    console.log(response.data);  // Handle the response data
  })
  .catch(error => {
    console.error('Error:', error);  // Handle the error
  });

First, the Axios library is imported. Then a GET request is sent using the axios.get() method to the endpoint (a mock endpoint is used in the example above). A promise method (.then()), which only executes when the request is successful, contains the code to handle the response data.

The response data from the endpoint is logged into the console. Axios automatically transforms the data to JSON data. The last piece of code in the Axios syntax is the logic for handling errors. Another promise method (.catch()) obtains information about what went wrong and logs the error to the console.

Fetch

The Fetch API is a built-in JavaScript API for making HTTP requests in web browsers. Like Axios, it is a promise-based HTTP client. It uses request and response objects to handle communications between an application and a server. Although Fetch API is native to web browsers, it can also be compatible with a Node environment by using the node-fetch library.

Key features of the Fetch API include:

  • It supports all HTTP methods.

  • It is promise-based, making it easier to handle asynchronous requests.

  • It has a clean and easy-to-use syntax.

  • It can handle a variety of response types such as JSON, text data, binary data, form data, etc.

Fetch API does not require installation as it is a built-in JavaScript feature.

Syntax

Here’s the syntax to make a GET request using Fetch:

fetch('api.mockendpoint.com/data')
.then((response) => {

console.log(response);
})
.catch((error) => {

console.error('Error:', error);
});

It is easier than the Axios GET request syntax. Here, the endpoint URL goes into the fetch() method, which is followed by a promise that handles the response from the server. Unlike Axios, the Fetch API does not automatically convert the data to JSON format. You can convert the response to JSON using the .json() method. Finally, the .catch promise handles the error, where you can log the error to the console or display it to the user.

Differences Between Axios and Fetch

In this section, we will discuss Fetch vs Axios, comparing both HTTP clients using criteria such as response handling, backward compatibility, intercepting HTTP requests and responses, response timeouts, and simultaneous request handling.

Handling Responses and Errors

One major difference between Axios and Fetch lies in how they handle responses, specifically the format in which the response data comes in. Axios automatically parses the response as JSON data, without any additional code. Consider the example below:

axios.get('api.mockendpoint.com/data')
  .then(response => {
    console.log(response.data);
  })
  .catch(error => console.error('Error:', error)); 

Here, the response.data logged to the console will be in JSON format, making it easier to reference the data.

Fetch does not automatically parse the response into JSON; you have to specify the format with some additional code. Here’s an example:

fetch('api.mockendpoint.com/data')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));

Notice the extra bit of code we added in the example above. We included the json() method so it parses the response into JSON format.

Axios and Fetch also differ in the way they handle errors. Axios automatically rejects errors outside the range of successful response codes (200-299), making it easier to catch the error with the catch() block. Consider this example:

axios.get('api.mockendpoint.com/data')
  .then(response => {
    console.log(response.data);
  })
  .catch(error => console.error('Error:', error));

The HTTP errors are caught automatically and logged to the console.

Fetch does not automatically reject errors based on their status code, you have to manually check for errors using the response.ok and response.status properties. Let’s see how this works:

fetch('api.mockendpoint.com/data')
  .then(response => {
    if (!response.ok) {
      throw new Error(HTTP error! Status: ${response.status});
    }
    return response.json();
  })
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));

Here, we see that there’s a conditional statement for handling the error. We first check if there’s an error using the response.ok property. If there is, it is identified and logged using the response.status property.

Backward Compatibility

Backward compatibility refers to the ability of a software or library to seamlessly support older or previous versions of related software. It ensures newer versions of a particular software (a browser or application in this case) can work with older versions without having compatibility issues.

Axios excels in this regard. It provides better backward compatibility and has wide browser support. It uses XMLHttpRequest which allows compatibility for older browsers like Internet Explorer 11.

Compared to Axios, Fetch has limited browser support. It only works on modern browsers like Chrome and Safari. To extend Fetch’s functionalities to older browsers, you have to use the whatwg-fetch polyfill. You can install it via NPM:

npm install whatwg-fetch --save

Then import:

import 'whatwg-fetch'
window.fetch(...)

Interceptors

Axios has support for HTTP requests and response interceptors. The need for interceptors may arise when you need to set a global behavior for handling requests or when you want to modify requests before they reach the then() or catch() block. Let’s see how it works:

//request
axios.interceptor.request.use(config => {
  console.log('Send a HTTP request');
  return config;
})
//response
axios.interceptors.response.use(
  response => response,
  error => {
    console.error('Interceptor error:', error);
    return Promise.reject(error);
  }
);

Here’s an interceptor being used to intercept a request. The expected behavior is that it logs a message before the request is sent.

Fetch does not provide built-in functionality to intercept requests or responses. However, you can manually use a middleware pattern to achieve that.

Response Timeouts

A response timeout is a situation where the server takes too long to respond to the client. If the server does not send a response to the client within a given duration, it is said to have a response timeout.

Axios provides a built-in timeout property that allows you to set a custom duration to handle requests that take too long, aborting the request if it exceeds the specified time. Here’s an example:

axios.get('api.mockendpoint.com/data', {
  timeout: 4000,
})
  .then(response => console.log(response.data))
  .catch(err => console.log(err.message))

Here, I set the timeout to 4000 milliseconds, meaning the request will be aborted and log an error if it takes longer than 4 seconds.

Fetch does not come with a timeout property but a similar behavior can be achieved using the AbortController. Here’s an example:

const TimeoutDemo = async ('api.mockendpoint.com/data', timeout = 4000) => {
  const controller = new AbortController(); 
  const signal = controller.signal;          

  // Set a timeout to abort the request
  const timeoutId = setTimeout(() => controller.abort(), timeout);

  try {
    const response = await fetch(url, { signal });            clearTimeout(timeoutId);

    if (!response.ok) {
      throw new Error(HTTP error! Status: ${response.status});
    }
    const data = await response.json();
    return data;
  } catch (error) {
    if (error.name === 'AbortError') {
      console.error('Fetch aborted due to timeout');
    } else {
      console.error('Fetch failed:', error.message);
    }
    throw error;
  }
};

Here, an instance of AbortController is created and the signal property is used to cancel requests. We set a timeout of 4000 using setTimeout, which calls the controller.abort() method after 4 seconds. If it exceeds the duration, it throws an AbortError. It’s important to implement logic that verifies the type of error that is being thrown, so an AbortError will indicate that the error is due to a response timeout.

Simultaneous Request Handling

Sometimes, you may want to make multiple requests to the server without worrying about the application’s performance. You can choose Axios or Fetch as they both come with the functionality to handle simultaneous requests.

In Axios, the axios.all() method contains all the request promises in an array, then the axios.spread() method is used to spread the responses into different arguments. Here’s an example:

axios.all([
  axios.get('api.mockendpoint.com/data1'),
  axios.get('api.mockendpoint.com/data2'),
  axios.get('api.mockendpoint.com/data3')
])
.then(axios.spread((response1, response2, response3) => {
  console.log('Response 1:', response1.data);
  console.log('Response 2:', response2.data);
  console.log('Response 3:', response3.data);
}))
.catch(error => {
  console.error('Error with one of the requests:', error);
});

In Fetch, we can achieve a similar behavior using the Promise.all() method like this:

const endpoints = [
  'api.mockendpoint.com/data1',
  'api.mockendpoint.com/data2',
  'api.mockendpoint.com/data3',
];

Promise.all(
  endpoints.map(endpoint => fetch(endpoint))
)
  .then(async ([ res1, res2, res3 ]) => {
    const response1 = await res1.json();
    const response2 = await res2.json();
    const response3 = await res3.json();
    console.log(response1, response2, response3);
  }))

Promise.all takes in an array of promises and executes them simultaneously. It waits for all the promises to be resolved before returning a response, which means if one of the promises fails, the entire operation fails and throws an error. Remember that Fetch does not automatically return data as JSON, so we had to include the .json() method to convert the response to JSON format.

Advantages of Axios over Fetch

  • It handles JSON data automatically.

  • It is fully compatible with the browser and in node environments.

  • It provides a built-in property to handle request timeouts.

  • It has full support for older browsers.

  • It has built-in Cross-Site Request Forgery protection.

Disadvantages of Axios

  • It requires manual installation as it is a third-party library.

  • It has a large bundle size which may slow down performance.

  • It may be overkill for small projects that require simple requests.

Advantages of Fetch over Axios

  • It is a built-in JavaScript API, which means no installation is needed.

  • It is lightweight and has a smaller bundle size, making it perform better.

  • It is easier to use and learn compared to Axios.

  • It works with most modern browsers.

Disadvantages of Fetch

  • An extra bit of code is required to handle JSON data.

  • It does not have built-in CSRF protection, which means any logic for security has to be manually implemented.

  • It does not have built-in support for request timeouts.

  • It does not have interceptors for requests and responses,

  • It has minimal support for older browsers.

Conclusion

In this blog post, you have learned about Axios vs Fetch, their features, and the key differences between them. Choosing the right HTTP client for your project ultimately depends on your project and the features of the HTTP client that best addresses your project’s needs.
Whichever HTTP client you choose, remember you can speed up your development time by having contextual solutions (as they relate to your codebase and overall workflow) provided by the Pieces Copilot. Try it out today. Happy coding!