# How to Make HTTP Requests using Axios in Node.js

By Atta Ur Rehman Shah (https://attacomsian.com/about). Published Apr 2, 2019, updated Sep 30, 2022. Topics: Node.js, JavaScript.
Canonical URL: https://attacomsian.com/blog/http-requests-axios

> Axios is a popular promise-based JavaScript HTTP client for making asynchronous HTTP requests. It works both in the browser and in the Node.js applications.

Axios is a popular [promise-based](https://attacomsian.com/blog/promises-javascript) HTTP client for making asynchronous HTTP requests in JavaScript. Axios provides a single API for dealing with both [XHR](https://attacomsian.com/blog/http-requests-xhr) in the browser and Node's [HTTP interface](https://attacomsian.com/blog/node-make-http-requests).

In this tutorial, you will learn how to add Axios to your Node.js project and [make HTTP requests](https://attacomsian.com/blog/http-requests-in-nodejs). To demonstrate Axios' use in a real-world scenario, we will use [Reqres](https://reqres.in/) REST API for all our examples.

## Installation

There are multiple options available to add Axios to your project. Depending on your package manager, you can either use npm:

```bash
$ npm install axios --save
```

or yarn:

```bash
$ yarn add axios
```

or bower:

```bash
$ bower install axios
```

or add directly to your web page using CDN:

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

## Basic API

To make an HTTP request,  simply create a new instance of Axios and then pass the relevant data to the `axios` object as shown below:

```javascript
const axios = require('axios')

// Send a GET request
axios({
  method: 'get',
  url: 'https://reqres.in/api/users',
  data: {
    name: 'Jane',
    country: 'Canada'
  }
})
```

For convenience, Axios also provides aliases for all supported HTTP request methods like `axios.get()`, `axios.post()`, and `axios.put()`.

## GET Request

The following example makes a GET API call to retrieve a list of users using the `axios.get()` method:

```javascript
const axios = require('axios');

const listUsers = async () => {
    try {
        const res = await axios.get('https://reqres.in/api/users');
        console.log(res.data.data);
    } catch (err) {
        console.error(err);
    }
};

listUsers();
```

In the above example, we used [async/await](https://attacomsian.com/blog/async-await-javascript) syntax, which is a part of ECMAScript 2017.

Alternatively, you can use promises to communicate with the REST API, as shown below:

```javascript
const axios = require('axios')

axios
  .get('https://reqres.in/api/users')
  .then(res => {
    console.log(res.data.data)
  })
  .catch(err => {
    console.log(err)
  })
```

## GET Request with Parameters

A GET request may contain query parameters in the URL. With Axios, you can either add parameters to the URL like below:

```javascript
axios.get('https://www.google.com/search?q=axios')
```

or use the `params` property in options:

```javascript
axios.get('https://www.google.com/search', {
    params: {
        q: 'axios'
    }
})
```

## POST Request

A POST request is used to create a new resource. Axios offers the `axios.post()` method to make an HTTP post request:

```javascript
const axios = require('axios')

const createUser = async () => {
  try {
    const res = await axios.post('https://reqres.in/api/users', {
      name: 'Atta',
      job: 'Freelance Developer'
    })
    console.log(res.data)
  } catch (err) {
    console.error(err)
  }
}

createUser()
```

## POST Request with `application/x-www-form-urlencoded`

By default, Axios transforms the request data object into a [JSON](https://attacomsian.com/blog/what-is-json) string. 

To send data in `application/x-www-form-urlencoded` format instead, you can either use the [qs](https://github.com/ljharb/qs) library or [querystring](https://nodejs.org/api/querystring.html) module for encoding data. 

Let's use the `qs` library as it has better support for nested objects. First, add the `qs` library to your project:

```bash
$ npm install qs --save
```

Now you can use the `qs` library as follows:

```javascript
const axios = require('axios')
const qs = require('qs')

const createUser = async () => {
  try {
    // set the url
    const url = 'https://reqres.in/api/users'

    // request data object
    const data = {
      name: 'John Doe',
      job: 'Blogger'
    }

    // set the headers
    const config = {
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
      }
    }

    const res = await axios.post(url, qs.stringify(data), config)
    console.log(res.data)
  } catch (err) {
    console.error(err)
  }
}

createUser()
```

## PUT Request

The `axios.put()` function can be used to update the user object as shown below:

```javascript

```

## DELETE Request

If you want to delete an object from the server using REST API with Axios, use the `axios.delete()` method:

```javascript
const axios = require('axios');

const deleteUser = async () => {
    try {
        const res = await axios.delete('https://reqres.in/api/users/2');
        console.log(res.status);
    } catch (err) {
        console.error(err);
    }
};

deleteUser();
```

## HEAD Request

A HEAD HTTP request is just a GET request without the response body. You can use the `axios.head()` method to make a HEAD request:

```javascript
const axios = require('axios')

const retrieveHeaders = async () => {
  try {
    const res = await axios.head('https://attacomsian.com')

    console.log(`Status: ${res.status}`)
    console.log(`Content Type: ${res.headers['content-type']}`)
    console.log(`Server: ${res.headers.server}`)
    console.log(`Date: ${res.headers.date}`)
  } catch (err) {
    console.error(err)
  }
}

retrieveHeaders()
```

Here is the output of the above example. It logs the response status code, `Content-Type`, server name, and date headers:

```bash
Status: 200
Content Type: text/html;charset=UTF-8
Server: nginx/1.14.0 (Ubuntu)
Date: Fri, 23 Aug 2019 11:53:30 GMT
```

## Multiple Concurrent Requests

Axios allows you to execute multiple HTTP requests in parallel. All you need to do is pass multiple URLs as an array to the `axios.all()` method. 

When all requests are finished, you will receive an array containing the response objects in the same order as they were sent:

```javascript
const axios = require('axios')

const loadUsers = async () => {
  try {
    const [res1, res2] = await axios.all(
      [
        axios.get('https://reqres.in/api/users/1'), 
        axios.get('https://reqres.in/api/users/2')
      ]
    )
    console.log(res1.data)
    console.log(res2.data)
  } catch (err) {
    console.error(err)
  }
}

loadUsers()
```

Alternatively, you can use `axios.spread()` to spread the array into multiple arguments:

```javascript
const axios = require('axios')

axios.all([
    axios.get('https://reqres.in/api/users/1'),
    axios.get('https://reqres.in/api/users/2')

]).then(axios.spread((res1, res2) => {
    console.log(res1.data)
    console.log(res2.data)
}))
```

## Error Handling

Since Axios is a promise-based library, handling errors is simple. We can use the `catch()` method of the promise to intercept any error that is thrown during the execution of the request:

```javascript
const axios = require('axios')

const unknown = async () => {
  try {
    const res = await axios.get('https://example.com/unkown')
    console.log(res.data)
  } catch (err) {
    if (err.response) {
      // the request went through and a response was returned
      // status code in 3xx / 4xx / 5xx range
      console.log(err.response.data)
      console.log(err.response.status)
      console.log(err.response.headers)
    } else if (err.request) {
      // request was made but the server returned no response
      console.log(err.request)
    } else {
      // something went wrong in setting up the request
      console.error('Error:', err.message)
    }
  }
}

unknown()
```

## Request Headers

To send custom request headers, pass an object containing the headers as the last argument:

```javascript
const axios = require('axios')

const createUser = async () => {
  try {
    // request data object
    const data = {
      name: 'Atta',
      job: 'Freelance Developer'
    }

    // request config that includes `headers`
    const config = {
      headers: {
        'Content-Type': 'application/json',
        'User-Agent': 'Axios',
        'X-Custom-Source': 'Axios Tutorial'
      }
    }

    const res = await axios.post('https://reqres.in/api/users', data, config)
    console.log(res.data)
  } catch (err) {
    console.error(err)
  }
}

createUser()
```

## Request Configuration

The following are the available configuration options for sending requests. Only the `url` is required. If there is no `method` provided, the request will default to GET:

```javascript
{
    // The URL to the request
    url: '/users'
    
    // HTTP methods like GET, POST, PUT, DELETE, HEAD
    method: 'GET',
    
    // optional base url to prepended to `url` 
    baseURL: 'https://example.com/api',

    // HTTP request headers
    headers: {
        'Content-Type': 'application/json'
    },

    // query string parameters
    params: {
        id: 420
    },    

    // request body data object
    data: {
        name: 'Atta'
    },

    // request timeout (in milliseconds)
    // default `0` (no timeout)
    timeout: 10000, 

    // should credential go with CORS request? 
    // default `false`
    withCredentials: false, 

    // http basic authentication 
    auth: {
        username: 'attacomsian',
        password: 'top$secret'
    },
    
    // the type of response expected
    // options are 'arraybuffer', 'document', 'json', 'text', 'stream'
    // in browser: `blob` is also available
    // default `json`
    responseType: 'json',

    // define the max. size of the HTTP response content in bytes
    maxContentLength: 2000,

    // defines the max. number of redirects to follow
    // if set to 0, no redirects will be followed.
    // default `5`
    maxRedirects: 5,

    // there are more options omitted from this list
    // for the sake of brevity
}
```

## Response Object

When we send an HTTP request to a server, it returns a response. The response object, returned by `axios`, contains the following information:

```javascript
{
  data: {}, // response that was provided by the server
  status: 200, //the HTTP status code from the server response
  statusText: 'OK', //the HTTP status message from the server response
  headers: {}, //the headers sent by the server (names are lowercased)
  config: {}, //the config that was provided to `axios` for the request
  request: {} //the request object that generated this response
}
```

The response data is automatically converted to a JSON object. so there is no need to parse it. 

## Summary

Axios is a Promise-based HTTP client library for the browser and Node.js.  It can be used with more advanced front-end frameworks like React or Vue.js and in your Node.js backend application.

* Axios provides HTTP request methods for all HTTP verbs e.g. `axios.get()`, `axios.post()`, `axios.put()` etc.
* Axios supports both async/await and promises.
* Axios automatically transforms the server response to a JSON object. So there is no need to use `JSON.parse()`.
* Axios provides `axios.all()` function for sending multiple requests simultaneously. 

For more configuration options, check out [Axios docs](https://github.com/axios/axios) on GitHub. If you want to use Axios in the browser, check out [How to use Axios in vanilla JavaScript](https://attacomsian.com/blog/axios-javascript) guide.
