How to Make HTTP Requests with Axios
Sending an HTTP request to an API is one of the most common things a developer does. However, there are many ways to send an API request. We can use a command-line tool such as cURL, use the browser’s native Fetch API, or install a package such as Axios.
Axios is an amazing tool for sending HTTP requests to your API. All popular browsers support Axios. You can use the package for your backend server, load it via a CDN, or require the package in your frontend application.
This article explores the following topics related to Axios:
- How to send basic CRUD requests to your API with Axios?
- How to send simultaneous requests?
- How to intercept requests and responses with Axios?
- How to configure XSRF protection for Axios requests?
- Which are the best Axios libraries?
- Why would you choose Axios over the Fetch API?
Before we start, let’s take a look at the different installation options.
Installation
There are different ways to install Axios, as mentioned in the introduction.
- Via NPM:
npm i --save axios
- Via CDN through a
script
tag:<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
For this tutorial, we’ll use the NPM option.
npm i --save axios
Next, we need to create a new project to experiment with Axios.
npm init -y
Following, let’s create a file called index.js
in the root of your project.
touch index.js
OK? We’re all set!
Exploring the Axios object
Let’s first learn how we can send a request with Axios and how the response looks like.
First of all, the Axios object exposes different methods that we can use to send specific requests. The below methods are aliases for all supported request methods.
axios.get(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])
axios.delete(url[, config])
axios.request(config)
axios.head(url[, config])
However, we can also pass an options object directly to the Axios instance. This options object specifies all details for the request we want to send. It’s an alternative to using one of the aliases. The example below illustrates a GET request. Also note how you can add custom headers to your request. We can also add a more standard header, such as Content-Type: application/json
.
const options = {
url: 'https://jsonplaceholder.typicode.com/todos/1',
method: 'get',
headers: {'X-Custom-Header': 'foobar'}
}
Axios basics: Sending CRUD API requests
In this section, let’s take a look at how we can send basic CRUD requests.
We’ll be using a publicly available JSON REST API for sending and retrieving data. The URL for this API is: https://jsonplaceholder.typicode.com/todos
. This API returns TODO data using the following format.
{
userId: 1,
id: 1,
title: 'my todo',
completed: false
}
Now, let’s load the Axios object. We can require the object directly into our index.js
file.
const axios = require('axios');
All good? Let’s learn how to send CRUD requests.
GET Request with Axios
We can send a GET request using the axios.get(url[, config])
method. As the first argument, we pass the URL for our API. Note that the URL ends with /todo/1
. We want to retrieve the TODO object with id
1
.
As we are using the async/await
syntax, we have to wrap the request by a try-catch
block. Don’t forget to call the function that encompasses the try-catch
block.
const getRequest = async () => {
try {
const response = await axios.get('https://jsonplaceholder.typicode.com/todos/1');
console.log(response.data);
} catch (err) {
console.error(err);
}
};
getRequest()
We capture the retrieved result in the response
variable. The Axios response
object contains the following properties.
{
// `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: {}
}
As the console.log
statement in our example snippet prints the data
field, we get the following JSON result.
{
userId: 1,
id: 1,
title: 'delectus aut autem',
completed: false
}
Now we understand how we can send a request and retrieve response data, let’s take a look at different HTTP methods.
POST Request with Axios
Following, let’s send a POST request.
axios.post(url[, data[, config]])
Here’s the code snippet that shows how you can pass data with your POST request.
const postRequest = async () => {
const newTodo = {
userId: 1,
title: 'Wash my hands',
completed: false
}
try {
const resp = await axios.post('https://jsonplaceholder.typicode.com/todos', newTodo);
console.log(resp.data);
} catch (err) {
console.error(err);
}
}
postRequest()
PUT Request with Axios
The PUT method allows you to update an entire object.
axios.put(url[, data[, config]])
Here’s the code snippet.
const putRequest = async () => {
// Update TODO object with ID 1
const updatedTodo = {
id: 1,
userId: 1,
title: 'Updated task title',
completed: true
}
try {
const resp = await axios.put('https://jsonplaceholder.typicode.com/todos/1', updatedTodo);
console.log(resp.data);
} catch (err) {
console.error(err);
}
}
putRequest()
DELETE Request with Axios
The DELETE method allows you to remove a resource.
axios.delete(url[, config])
Below, you find an example.
const deleteRequest = async () => {
try {
const resp = await axios.delete('https://jsonplaceholder.typicode.com/todos/1')
console.log(resp.data);
} catch (err) {
// Handle Error Here
console.error(err);
}
}
deleteRequest()
Done! We’ve covered all CRUD operations. Let’s explore how we can send simultaneous requests.
Sending simultaneous requests with Axios
Axios provides a similar alternative to the Fetch API’s Promise.all()
method: axios.all()
. This method accepts an array of Axios requests. If all requests finish successfully, we receive an array that contains all responses.
Let’s take a look at how we can request multiple TODO items.
const multipleRequests = () => {
axios.all([
axios.get('https://jsonplaceholder.typicode.com/todos/1'),
axios.get('https://jsonplaceholder.typicode.com/todos/2')
])
.then(responseArray => {
//this will be executed only when all requests are successful
console.log('=> Request ID: ', responseArray[0].data.id);
console.log('=> Request ID: ', responseArray[1].data.id);
});
}
multipleRequests()
// logged output:
// => Request ID: 1
// => Request ID: 2
As you can see, the responseArray
variable contains all responses.
If you don’t like using a response array, we can immediately destructure this array as shown in the example below.
const multipleRequests = async () => {
// Use destructuring and await syntax
const [req1, req2] = await axios.all([
axios.get('https://jsonplaceholder.typicode.com/todos/1'),
axios.get('https://jsonplaceholder.typicode.com/todos/2')
])
}
multipleRequests()
Axios request and response intercepting
Axios provides us with some exciting functionality to intercept both requests and responses. It allows us to intercept the request or response object before they are handled by then
or catch
. This functionality gives us many possibilities, such as:
- Automatically adding headers for each request object like authorization headers
- Transporting response errors to a monitoring tool for analysis
- Modifying a response object to a different format
The below interceptor example shows how we can modify the request with an extra property and log some useful data. Next, we send a request to check if the interceptor works.
We can access interceptors directly from the imported axios
object. Using the use
method, we can overwrite the default behaviour with our custom logic.
axios.interceptors.request.use(config => {
config.name = 'my-axios-app'
console.log(`Sending ${config.method} request to: ${config.url}`);
return config;
}, error => {
return Promise.reject(error);
});
// send GET request
axios.get('https://jsonplaceholder.typicode.com/todos/1')
Furthermore, let’s log error data and add a timestamp to the error object when the request fails. Here, you can add code to send error data to a frontend monitoring tool, such as OpenReplay.
To test the response interceptor, let’s request a TODO with a non-existing ID.
axios.interceptors.response.use(response => {
return response;
}, error => {
console.log('Request failed for: ', error.config.url)
error.timestamp = Date.now()
return Promise.reject(error);
});
// send an incorrect GET request
const invalidRequest = async () => {
try {
const resp = await axios.get('https://jsonplaceholder.typicode.com/todos/incorrect-id')
} catch (error) {
console.log('Something went wrong at timestamp: ', error.timestamp)
}
}
invalidRequest()
Open Source Session Replay
OpenReplay is an open-source, session replay suite that lets you see what users do on your web app, helping you troubleshoot issues faster. OpenReplay is self-hosted for full control over your data.
Start enjoying your debugging experience - start using OpenReplay for free.
Does Axios support XSRF headers?
”Cross-Site Request Forgery is one of the most popular ways of exploiting a server. It attacks the server by forcing the client to perform an unwanted action. This attack targets applications where the client/user is already logged in. It mainly changes the state of the server by making inadvertent updates or transfer of data.”
Luckily, Axios provides protection against cross-site request forgery (XSRF). To prevent this type of attack, we can configure an XSRF cookie and header via the options object. This is how you can achieve it.
const options = {
url: 'https://jsonplaceholder.typicode.com/todos',
method: 'post',
data: addTodo,
xsrfHeaderName: 'X-XSRF-TOKEN',
xsrfCookieName: 'XSRF-TOKEN'
};
// send the request by passing the options object
await axios(options);
That’s it!
Which are the best Axios libraries?
Axios is so popular among developers that a whole ecosystem of third-party libraries has been created. Many libraries modify the Axios source code or help you with specific tasks. For example, the axios-response-logger library helps you with various ways of logging Axios responses using interceptors.
Here’s an overview of popular Axios libraries:
- vue-axios: A small wrapper for integrating Axios to Vuejs
- redux-axios-middleware: Redux middleware for fetching data with axios HTTP client
- axios-api-versioning: Adds easy-to-manage API versioning to Axios
- react-hooks-axios: This library adds custom React Hooks for Axios
- axios-logger: When you send a request in nodejs, you need to show the log to the console. This library display the necessary information while communicating with the server. Very similar to the
axios-response-logger
library. - jest-mock-axios: This library provides functionality to mock Axios requests for unit testing with Jest.
Axios vs. Fetch API: Which is best?
To conclude this article, let’s provide you with some specific arguments to choose Axios over the browser’s Fetch API. Both solutions work well. However, Axios focuses on ease of use while not everything is as straightforward using the Fetch API.
Here are five arguments why you would choose Axios:
- Axios lets you quickly configure the timeout property.
- Axios’ syntax is more straightforward. For instance, it uses aliases.
- Axios provides an easy way to track upload progress via its request config.
- Axios interceptors are a great feature to automate specific tasks for requests.
- Axios supports automatic JSON stringification when sending requests. While using the Fetch API, we have to do this manually.
On the other hand, we’re loading a library into our project while the Fetch API is already there. In the end, the Axios library won’t increase your total project size by much.
In the end, it’s a personal preference! Axios has gained a lot of popularity as it’s a bit more comfortable to use than the browser’s Fetch API.