How to master HTTP requests with Axios
Tags: programming, javascript, node, webdev
Published: 2023-02-06 09:24:01

---
title: How to master HTTP requests with Axios
published: true
description: Let's dive deep into Axios to understand its features and why it has become an overwhelmingly popular library for handling HTTP requests with JavaScript in both the browser and the server.
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/60qszn0smuc0uhv54oyv.jpg
date: 2023-01-06 19:38:21 UTC
tags: Programming,JavaScript,NodeJS,WebDevelopment
canonical_url: https://livecodestream.dev/post/how-to-master-http-requests-with-axios/
---

[Axios](https://github.com/axios/axios) is one of the favorite HTTP clients among Javascript developers. It is a promise-based HTTP client used to send HTTP requests, especially AJAX requests, from the client side as well as the server side.

Sending HTTP requests from the Javascript side is now almost a necessity when developing dynamic web applications. Axios simplifies this task by providing an easy-to-use abstraction over Javascript’s XMLHttpRequest interface with several user-friendly functions and configuration options.

In this tutorial, we will walk through everything you need to know about sending HTTP requests with Axios with code examples and simplified explanations.

Let’s start our introduction with this question.

----

## Why You Should Choose Axios?

Axios has several advantages over other HTTP clients, such as jQuery’s AJAX, the native XMLHttpRequest library, and fetch. It is a lightweight package with excellent support for client-side and server-side requests, which means it can run on NodeJS or the browser.

The syntax of Axios is simple and intuitive, making it easy to work with even for novice developers.

Recently the Fetch API has been gaining some popularity for sending requests. However, Axios still provides several advantages over the same:

- Support for request and response interception
- Ability to cancel Axios requests
- Automatic transforms for JSON data (Axios serializes javascript objects into JSON and vice versa)
- Automatic data object serialization to `multipart/form-data` and `x-www-form-urlencoded` body encodings
- Client-side support for XSRF protection

----

## How to install Axios

You can install and use Axios on both the front-end and back-end. The installation is simple if you are using a package manager like npm.

```bash
npm install axios
```
If you use a content delivery network (CDN), embed the Axios script in HTML.

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

Or,

```html
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
```

----

## Send  HTTP Requests with Axios

Axios is simple. To start an HTTP request, you can use the Axios main function, passing an object with all the request parameters, options, and data like in the following example:

```javascript
axios({
    method: "post",
    url: "/users",
    data: {
        username: "sam123",
        firstname: "sam",
        lastname: "smith"
    }
});
```

As can be identified, the Axios library will initiate a POST request against the given URL and send some data to the server.

That's a simple example, but Axios provides much more features that can be enabled in this request object. To learn more about it, refer to its [official documentation](https://www.npmjs.com/package/axios#creating-an-instance).

That's way number one to send requests, but there is another, which I prefer as it is more explicit, which is using dedicated request functions for each HTTP method.

Here is the list of supported methods:

```javascript
axios.delete(url[, config]);
axios.head(url[, config]);
axios.options(url[, config]);
axios.post(url[, data[, config]]);
axios.put(url[, data[, config]]);
axios.patch(url[, data[, config]]);
```

### Axios GET request example

The beauty of Axios is in its simplicity while giving the user multiple options. Say, for instance, that you need to make a GET request to the URL: `/users?firstName=jc`. You could simply write the following Axios GET request code:

```javascript
axios.get('/user', {
    params: {
      firstName: 'jc'
    }
  })
  .then(function (response) {
    // handle success
    console.log(response);
  });
```

But alternatively, you can pass the parameters as part of the URL string. However, This may not be a best practice; it's cleaner when working with variables, and Axios will automatically sanitize the inputs, which won't do if you provide the values directly as part of the URL.

But in some cases, it makes sense to avoid sanitization, e.g., when sending certain API keys over query parameters. Here is the same request not using `params`.

```javascript
axios.get('/user?firstName=jc')
  .then(function (response) {
    // handle success
    console.log(response);
  });
```

Both examples of Axios GET requests handle only the happy path, but since Axios is promise based, you can also catch errors and run code in either condition.

### Axios POST Request Example

When working with POST requests (also similar to PATCH and PUT), it is very common to send data to the server, and if you are working with [REST APIs](/post/what-is-a-rest-api/), chances are you are sending data in JSON format. The beauty of Axios in working with REST is that it will automatically transform JS objects into JSON when sending data and will convert the responses from JSON into JS objects so that you can directly work with them.

Let's see an example of an Axios POST request.

```javascript
axios.post('/user', {
    firstName: 'jc',
    lastName: 'M'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });
```

> With Axios, there's no need to convert JS objects or stringify, you simply pass the Axios POST request the URL and the object, and Axios will take care of everything else.
----

## Handle Responses with Axios

When we send an HTTP request to a remote server, we receive a response from that server containing certain information. We can retrieve this response using Axios.

According to Axios documentation, the returned response contains the following information.

```javascript
{
  // `data` is the response that was provided by the server
  data: {},
  // `status` is the HTTP status code from the server response
  status: 200,
  // `statusText` is the HTTP status message from the server response
  statusText: 'OK',
  // `headers` the HTTP headers that the server responded with
  // All header names are lower cased and can be accessed using the bracket notation.
  // Example: `response.headers['content-type']`
  headers: {},
  // `config` is the config that was provided to `axios` for the request
  config: {},
  // `request` is the request that generated this response
  // It is the last ClientRequest instance in node.js (in redirects)
  // and an XMLHttpRequest instance in the browser
  request: {}
}
```

Since Axios is promise-based, the response is returned as a promise. So we need to use `then()` and `catch()` functions to retrieve the response and catch errors if there are any.

Let’s see how we can handle the response returned by a POST request.

```javascript
axios.post("/users", {
    username: "sam123",
    firstname: "sam",
    lastname: "smith"
    })
    .then(response => {
        console.log(response);
        console.log(response.data);
        console.log(response.data.userId);
        console.log(response.status);
        console.log(response.statusText);
    })
    .catch(error => {
            console.log(error.message);
    });
```

----

## Use Async/Await

We can also use async/await to send HTTP requests and handle responses instead of promises.

```javascript
async function getUserData() {
    try {
        const response = await axios.get("/users/sam123");
        console.log(response);
    }
    catch (error) {
        console.log(error);
    }
}
```

----

## Working with concurrent requests

In the previous section, we used Promise.all() method to send multiple concurrent requests. When all the requests passed to the method are completed, it returns a single promise with response objects of every request. We can separate the responses using the index of each request in the array passed to the method.

```javascript
Promise.all([
    axios.get("/users/sam123"),
    axios.get("/users/sam123/comments")
    ])
    .then(response => {
       const user = response[0].data
       const comments = response[1].data
    })
    .catch(error => {
        console.log(error);
    });
```

-----

## Error handling with Axios and HTTP status code

If an error occurs when sending an HTTP request with Axios, the returned error object contains specific information to help us determine exactly where the error occurred.

Errors could occur in any of the following three areas:

- The request responded with a status code out of the range of 2xx
- Time out, the request was made, but no response was received
- Something else blew up when setting up the request

With Axios, you can identify these different scenarios and act accordingly. Here is some example code that can help you get started

```javascript
axios.get('/user?firstName=jc')
  .catch(function (error) {
    if (error.response) {
      // The request was made and the server responded with a status code
      // that falls out of the range of 2xx
      console.log(error.response.data);
      console.log(error.response.status);
      console.log(error.response.headers);
    } else if (error.request) {
      // Time out, the request was made, but no response was received
      // `error.request` is an instance of XMLHttpRequest in the browser and an instance of
      // http.ClientRequest in node.js
      console.log(error.request);
    } else {
      // Something else blew up when setting up the request
      console.log('Error', error.message);
    }
    console.log(error.config);
  });
```

----

## Transform Data with Axios
We talked about how Axios will transform data automatically into and from JSON for you, but what if you require any other transformations? For example, working with some APIs is common to see attributes in snake-case (e.g., first_name). However, we don't want snake-case in our JS code. We want something like "firstName" instead.

For purposes like these, Axios provides a feature that allows you to transform requests and responses with two simple functions:

```javascript
axios({
    method: "post",
    url: "users/sam123",
    data: {
        username: "sam123",
        firstname: "sam",
        lastname: "smith"
    },
    // `transformRequest` allows changes to the request data before it is sent to the server
    // This is only applicable for request methods 'PUT', 'POST', 'PATCH' and 'DELETE'
    // The last function in the array must return a string or an instance of Buffer, ArrayBuffer,
    // FormData or Stream
    // You may modify the headers object.
    transformRequest: [(data, headers) => {
        //Transform request data as you prefer
        return data;
    }],
    // `transformResponse` allows changes to the response data to be made before
    // it is passed to then/catch
    transformResponse: [(data) => {
        //Transform the response data as you prefer
        return data;
    }]
});
```

----

## Intercept Requests

HTTP request interception is one of the most interesting features in Axios. It allows you to intercept requests sent by and requests received by your program and carry out some common tasks before the operation is complete. This feature simplifies handling background tasks related to HTTP requests, such as logging, authentication, and authorization.

Defining an interceptor for either requests or responses is a simple task.

```javascript
axios.intercept.request.use(config => {
    //Intercept the request and do something before it is sent
    console.log("Request sent");
    return config;
}, error => {
    return Promise.reject(error);
});
axios.get("/users/sam123")
    .then(response => {
        console.log(response.data);
    });
```

Here, the config object is the exact config object we pass the Axios function or one of its aliases. So the interceptor has full access to the request config and its data.

After setting the request interceptor, every time a new request is sent by the program, we print the message: "Request sent" to the console.

We can similarly set a response interceptor.

```javascript
axios.intercept.response.use(config => {
    //Intercept the response and do something when it is received
    console.log("Response recieved");
    return config;
}, error => {
    return Promise.reject(error);
});
axios.get("/users/sam123")
    .then(response => {
        console.log(response.data);
    });
```

Every time we receive a response, we print the message: "Response received" to the console.

We can define interceptors for instances instead of the Axios object as well.

```javascript
instance.intercept.request.use(config => {
    //Intercept the request and do something before it is sent
    console.log("Request sent");
    return config;
}, error => {
    return Promise.reject(error);
});
```

----

## Cancel Requests with Axios

There are some cases in web development where we might find the response from the remote server to our request is no longer important. In such cases, we can save the system resources by simply canceling the request (I know, most of the time, developers don't, but we should). And Axios provides us with a method to do just that, in a very similar way to Fetch, by using the [AbortController](https://developer.mozilla.org/en-US/docs/Web/API/AbortController).

```javascript
const controller = new AbortController();
axios.get('/foo/bar', {
   signal: controller.signal
}).then(function(response) {
   //...
});
// cancel the request
controller.abort()
```

You may see in some older code the use of the [Axios cancel token API](https://axios-http.com/docs/cancellation). However, that method has been deprecated by the more friendly and standard AbortController.

----

## Set Custom Headers for Requests

You can easily set custom headers for the requests you are sending with Axios. You only have to pass an object containing the custom headers to the request method you are using.

```javascript
const options = {
    headers: {"X-Custom-Header": "value"}
}
axios.get("users/sam123", options);
```

----

## Set Config Defaults

In a given application is common to have a base set of configurations that would apply to all web requests; it could be something like a base URL, some headers, etc. But if your application uses Axios multiple times in multiple files, it could end up being messy to repeat the same code over and over again.

That's where config defaults come in. They allow you to set default configuration options for all Axios requests.

For example, if you want to set the base URL or an authorization header for every request, it can be easily achieved, as the following example shows.

```javascript
axios.defaults.baseURL = "https://example.com";
axios.defaults.headers.common["Authorization"] = AUTH_TOKEN
```

## Set Config Defaults of Instances
Sometimes, setting default configurations for every HTTP request becomes unrealistic due to the differences in requests we send: we could send requests to two different APIs or with different authorization tokens depending on the user permissions.

In such cases, though we are not able to find config options common to every request, we might be able to find options common to different groups of requests. Axios provides us with a way to set default configs for these different groups separately.

It’s by creating instances.

We can create separate instances and set default configs for each instance. Then, we can use this instance object to send requests instead of the Axios object.

```javascript
// Create new instance
const instance = axios.create();
// Set config defaults for the instance
instance.defaults.baseURL = "https://example.com";
instance.defaults.headers.common["Authorization"] = AUTH_TOKEN;
// Send requests using the created instance
instance.get("/users", {
    params: {
        firstname: "sam"
    }
});
```

----

## Protect against XSRF Attacks

Cross-site request forgery (XSRF) is a technique used by attackers to infiltrate web applications and carry out malicious tasks. In these attacks, the attacker disguises as a trusted user and tricks the application into executing actions for their benefit.

This could compromise the privacy and security of the user and even result in the attacker gaining access to the entire system if the user has high-level permission.

Axios provides a way to prevent such attacks by embedding additional authentication information when creating the request. This is how it is implemented.

```javascript
const options = {
  xsrfCookieName: 'XSRF-TOKEN',
  xsrfHeaderName: 'X-XSRF-TOKEN',
};
axios.post("/users", options);
```

----

## Popular Axios libraries to extend its functionality

- [axios-mock-adapter](https://github.com/ctimmerm/axios-mock-adapter): Axios adapter that allows easy mock requests
- [axios-hooks](https://github.com/simoneb/axios-hooks): React hooks for Axios, with built-in support for server-side rendering.
- [axios-retry](https://github.com/softonic/axios-retry): Axios plugin that intercepts failed requests and retries them whenever possible.
- [moxios](https://github.com/axios/moxios): Mock Axios requests for testing
- [axios-extensions](https://github.com/kuitos/axios-extensions): 🍱 Axios extensions lib, including throttle, cache, retry features, etc...
- [axios-cache-adapter](https://github.com/RasCarlito/axios-cache-adapter): Caching adapter for Axios. Store request results in a configurable store to prevent unneeded network requests.
- [axios-curlirize](https://github.com/anthonygauthier/axios-curlirize): Axios plugin converting requests to cURL commands, saving and logging them.

-----

## FAQs

### Can I use Axios with React, Vue, or Angular?"

Yes, you can use Axios with React or any other JS framework, as Axios can run on the browser or the server.


### What is the difference between Fetch API and Axios?

Axios provides more features out of the box than Fetch API; with that said, all those features have equivalents with Fetch but would require more code to get them to work. So if you don't mind installing a lightweight library to handle your requests, Axios is a great option, with more features and a very likable API.

### Can I mock Axios for unit testing?"

Yes, you can write unit tests for applications using Axios, and you can mock the Axios API. Here is an example:

```javascript
import axios from 'axios';
// Mock out all top level functions, such as get, put, delete and post:
jest.mock("axios");
// ...
test("good response", () => {
  axios.get.mockImplementation(() => Promise.resolve({ data: {...} }));
  // ...
});
test("bad response", () => {
  axios.get.mockImplementation(() => Promise.reject({ ... }));
  // ...
});
```

----

## Conclusion

In this article, we explained what Axios is and why it is a great choice for your project. We also gave examples of working with GET and POST requests and more advanced features like API intercept request, default request config, transforms, handling errors, and more.

Axios is a great library for making HTTP requests, and it provides developers with many features that can help them make the most out of their applications. We hope this article has provided enough information to use Axios in your projects.

Thanks for reading, and happy requests!

----

**Newsletter**  
  
[Subscribe to my weekly newsletter](https://livecodestream.dev/newsletter/) for developers and builders and get a weekly email with relevant content.