DEV Community

Alessio Michelini
Alessio Michelini

Posted on

Some practical examples on why I prefer Axios over Fetch

I want to be clear from the very start, this is not a post of why "you should always avoid fetch", as for what you do and you know the limitations and how to get around it, and you are happy with that, that's totally ok for me.

But, I often see comments across our team where people ask why we use axios, a library to fetch data from a resource, then using the native fetch library.
And to be fair is a totally valid question in my opinion.

We could argue on the advantages on using one instead of the other and vice-versa, like you don't need any dependencies for fetch (unless you need to support old browsers and use a polyfill) or the other can give you a better degree of tuning, but I'm a practical person and I prefer to show practical examples, and let the code explain why I prefer X over Y.

Let's have this simple case, where you have to fetch some data from an API, and I want to check if the request is successful or not.
Normally I prefer to wrap calls like this into a try..catch statement, so I can catch the error if the request fails:

const axios = require('axios');

const TEST_ENDPOINT = 'https://somedomain.com/api/someendpoint';

(async () => {
  try {
    await fetch(TEST_ENDPOINT);
    console.log('using fetch: all good');
  } catch (error) {
    console.error('using fetch: error');
  }
})();

(async () => {
  try {
    await axios.get(TEST_ENDPOINT);
    console.log('using axios: all good');
  } catch (error) {
    console.error('using axios: error');
  }
})();
Enter fullscreen mode Exit fullscreen mode

My expectation would be that they both act the same, if the request is successful, I'll se the all good message, but if the API returns anything else than a 200 OK status header, it should throw an error.

But if you run the code above, this will happen:

using fetch: all good
using axios: error
Enter fullscreen mode Exit fullscreen mode

Why with fetch I get the all good message?

That's because fetch doesn't throw any error if the request fails, it will just rely on the code to handle that by looking at the response from the request, using either the status or ok properties,
while with axios if a request fails, it will throw an error immediately.
So to make your fetch request works properly, you will need to add some extra code:

(async () => {
  try {
    const result = await fetch(TEST_ENDPOINT);
    if (!result.ok) {
      throw new Error('Not found');
    }
    console.log('using fetch: all good');
  } catch (error) {
    console.error('using fetch: error');
  }
})();
Enter fullscreen mode Exit fullscreen mode

Again, if you are ok to add this extra check, I'm totally ok to use fetch.

Now, let's say that we are expecting the response to be a JSON object, and we want to use that in our code.
With axios, you just need to fetch the data property from the axios response, and it's already a JSON object, no need to do any transformation or call any functions, it's ready to go.

With fetch you have to get the response from the request, and use the json() function to transform the raw data into a JSON object.
When you add with the previous error checking, to do the same exact job, you will have your code that will look like this:

// Fetch
const response = await fetch(TEST_ENDPOINT);
if (response.status !== 200) {
  throw new Error('Not found');
}
const data = await response.json();

// Axios one liner
const { data } = await axios.get(TEST_ENDPOINT);
Enter fullscreen mode Exit fullscreen mode

The code above does the same exact thing, but with axios is one line of code, while with fetch is 5.
And when you build large applications, it can become tedious to keep adding the same controls, unless you create your own wrap function, which again is more code that you have to maintain.

Is this a deal breaker for you? Maybe not, maybe you do just an handful of requests in your application, and that's totally fine to use fetch, especially if you don't want to have more dependencies.

What about doing requests that don't use the GET method?

Let's say I want to send some data to an API?
With fetch you will have something like this:

const yourPostData = {
  name: 'Alessio',
  age: 25,
};

const response = await fetch('https://example.com/profile', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(yourPostData),
});

const result = await response.json();
Enter fullscreen mode Exit fullscreen mode

So you have to pass an object, telling fetch to use the POST method, transform the data into a string, and pass the headers to tell it to encode it as application/json.
Then to read the response we'll need to transform the data back to JSON.

The same above with axios is again, excluding the input data, a one liner code:

const yourPostData = {
  name: 'Alessio',
  age: 25,
};

const { data } = await axios.post('https://example.com/profile', yourPostData);
Enter fullscreen mode Exit fullscreen mode

Personally I prefer to have brevity of code, at the expense of a small dependency. Again, it's more than that, these are just two simple examples to explain my point in the argument, and if you are ok to write more verbose code, or create your own wrapper, that's totally ok.

Top comments (1)

Collapse
 
framemuse profile image
Valery Zinchenko

What you mentioned in the article was talked about lots of times.

You're saying that there are something more than what you've mentioned, so please share it instead.