Fetch vs. Axios: Choosing the Right Tool for HTTP Requests

Ahmed RazaAhmed Raza
4 min read

When it comes to making HTTP requests in JavaScript applications, two popular options often stand out: Fetch API and Axios. Both are effective in fetching data or sending requests to APIs, but their functionality, syntax, and usability differ significantly. This article will compare Fetch and Axios, providing use cases and practical examples to help developers determine the right tool for their projects.


Overview of Fetch API

Fetch API is a native JavaScript feature introduced in ES6. It provides a simple, promise-based mechanism for making HTTP requests. Since it is built into modern browsers, it doesn't require installing additional libraries.

Key Features of Fetch:

  1. Built-in: Available by default in modern browsers.

  2. Promise-based: Uses JavaScript Promises for asynchronous operations.

  3. Modular and flexible: Can be combined with other JavaScript libraries for enhanced functionality.

Limitations:

  1. Error Handling: Fetch does not reject promises for HTTP error statuses (e.g., 404 or 500).

  2. Verbose Syntax: Requires additional code for advanced configurations like timeout handling or response transformation.

  3. No Interceptors: Lacks the ability to modify requests or responses globally.


Overview of Axios

Axios is a popular third-party library that simplifies HTTP requests. It is based on Promises and provides a rich feature set that addresses some limitations of the Fetch API.

Key Features of Axios:

  1. Request Interceptors: Modify requests before they are sent or responses after they are received.

  2. Automatic JSON Handling: Automatically transforms response data to JSON format.

  3. Timeouts: Built-in support for request timeouts.

  4. Browser Compatibility: Includes support for older browsers (via polyfills).

  5. Node.js Support: Can be used in server-side applications.

Limitations:

  1. Library Size: Requires installation and increases bundle size compared to the native Fetch API.

  2. Dependency: Being an external library, it may require updates or maintenance over time.


Practical Comparison

1. Basic GET Request

Using Fetch:

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

Using Axios:

import axios from 'axios';

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

Key Takeaway: Axios simplifies error handling and data transformation compared to Fetch.


2. Adding Custom Headers

Using Fetch:

fetch('https://api.example.com/data', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer token123',
    'Content-Type': 'application/json'
  }
})
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));

Using Axios:

axios.get('https://api.example.com/data', {
  headers: {
    'Authorization': 'Bearer token123',
    'Content-Type': 'application/json'
  }
})
  .then(response => console.log(response.data))
  .catch(error => console.error('Error:', error));

Key Takeaway: Both approaches handle custom headers efficiently, but Axios is often more concise.


3. POST Request with Data

Using Fetch:

fetch('https://api.example.com/data', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ name: 'John', age: 30 })
})
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));

Using Axios:

axios.post('https://api.example.com/data', {
  name: 'John',
  age: 30
})
  .then(response => console.log(response.data))
  .catch(error => console.error('Error:', error));

Key Takeaway: Axios automatically handles JSON.stringify, reducing boilerplate code.


4. Global Interceptors

Using Fetch: Implementing request or response interceptors with Fetch requires manual setup:

async function fetchWithInterceptor(url, options) {
  // Request Interceptor
  console.log('Request URL:', url);
  const response = await fetch(url, options);

  // Response Interceptor
  if (!response.ok) {
    throw new Error('Response error');
  }
  return response.json();
}

fetchWithInterceptor('https://api.example.com/data', { method: 'GET' })
  .then(data => console.log(data))
  .catch(error => console.error(error));

Using Axios:

axios.interceptors.request.use(config => {
  console.log('Request:', config);
  return config;
});

axios.interceptors.response.use(
  response => response,
  error => {
    console.error('Response error:', error);
    return Promise.reject(error);
  }
);

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

Key Takeaway: Axios provides built-in support for interceptors, making it a better choice for managing global request/response logic.


Use Cases

  1. When to Use Fetch:

    • Minimal projects with straightforward HTTP requirements.

    • Applications where reducing bundle size is a priority.

    • Environments where Fetch’s native support is sufficient.

  2. When to Use Axios:

    • Applications requiring advanced features like interceptors, automatic data transformations, or timeout handling.

    • Projects that integrate with Node.js or older browsers.

    • Scenarios where reducing repetitive boilerplate code is essential.


Conclusion

Both Fetch and Axios are powerful tools for handling HTTP requests, but their use cases differ. Fetch, being native, is lightweight and suitable for simpler tasks, while Axios excels in projects demanding more robust functionality and concise code. Choosing between the two depends on project requirements, developer preferences, and the desired balance between simplicity and advanced features.

0
Subscribe to my newsletter

Read articles from Ahmed Raza directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Ahmed Raza
Ahmed Raza

Ahmed Raza is a versatile full-stack developer with extensive experience in building APIs through both REST and GraphQL. Skilled in Golang, he uses gqlgen to create optimized GraphQL APIs, alongside Redis for effective caching and data management. Ahmed is proficient in a wide range of technologies, including YAML, SQL, and MongoDB for data handling, as well as JavaScript, HTML, and CSS for front-end development. His technical toolkit also includes Node.js, React, Java, C, and C++, enabling him to develop comprehensive, scalable applications. Ahmed's well-rounded expertise allows him to craft high-performance solutions that address diverse and complex application needs.