Using Axios for Network Requests in React
Before jumping ship to React, I had been working on Angular for a long time and really enjoyed building great SPAs in the MVVM Pattern. One of my favorite things was the services architecture of making requests. I’ve tried to recreate the pattern using Axios, which you can use in React or any other frontend framework.
First, let’s define a custom wrapper around Axios
for our application. This
can contain our global configuration such as the base API url, header defaults
and more:
import axios from 'axios'
import constants from 'shared/constants'
/**
* Create an Axios Client with defaults
*/
const client = axios.create({
baseURL: constants.api.url
});
/**
* Request Wrapper with default success/error actions
*/
const request = function(options) {
const onSuccess = function(response) {
console.debug('Request Successful!', response);
return response.data;
}
const onError = function(error) {
console.error('Request Failed:', error.config);
if (error.response) {
// Request was made but server responded with something
// other than 2xx
console.error('Status:', error.response.status);
console.error('Data:', error.response.data);
console.error('Headers:', error.response.headers);
} else {
// Something else happened while setting up the request
// triggered the error
console.error('Error Message:', error.message);
}
return Promise.reject(error.response || error.message);
}
return client(options)
.then(onSuccess)
.catch(onError);
}
export default request;
Making Requests using Services
To make a simple request, we can use something like this:
import request from 'shared/lib/request'
request({
method: 'get',
url: '/path/'
}).then((resp) => {
console.log(resp);
})
But the ideal way to use it is to create a separate service
for each resource
that should be responsible for handling all API calls of that model. For example,
for a Message
class, we can create a MessageService
:
// services/api/message.js
import request from 'shared/lib/request'
function get(id) {
return request({
url: `/message/${id}`,
method: 'GET'
});
}
function create({subject, content}) {
return request({
url: '/message/create',
method: 'POST',
data: {
subject,
content
}
});
}
const MessageService = {
get, create //, update, delete, etc. ...
}
export default MessageService;
You can then call these methods from any other module/view/component:
import React from 'react'
import MessageService from 'services/api/message'
class Message extends React.Component {
handleSubmit() {
const {subject, message} = this.state;
MessageService
.create({subject, message})
.then((response) => {
alert(`New Message with id ${response.id} created!`);
});
}
// Other stuff...
}