This content originally appeared on DEV Community and was authored by Rahul Kasana
One common thing in most web apps is API calling. So often the first thing I usually end up making in any web app is a request wrapper.
Why is it needed and how it helps -
- Prevent writing repetitive code.
- Enforcing code structure by defining the API cases only once.
- Adding multiple enhancements in future like performance monitoring by firebase.
- Getting environment based URL as well as Authentication tokens.
- Handle basic error codes and show errors to user from 1 place.
Prerequisites
To create the wrapper we'd be using axios and qs for querystring parsing and stringifying.
Run this command to install them -npm install axios && npm i qs
Setting up baseURL for API in .env file like this
REACT_APP_API_HOST=https://api.example.io/v1
Usage in redux files
It's generally good practice to define URL's as constants module specific in one file as well.
import { DoRequest, REQUEST_TYPE } from "../../helpers/doRequest";
let response = await DoRequest({
method: REQUEST_TYPE.POST,
url: '/login'
});
Example usage in reducer
Defining the API Wrapper and its use cases for each line
API Wrapper Code
import axios from "axios";
import qs from "qs";
import { useDispatch } from "react-redux";
import { logout } from "../../store/authReducer";
export const REQUEST_TYPE = {
POST: "post",
GET: "get",
PUT: "put",
DELETE: "delete",
};
export const DoRequest = async (requestData) => {
const dispatch = useDispatch();
const token = localStorage.getItem("token"); //Authorization token to use for API's
const defaultHeader = {
Authorization: token ? `Token ${token}` : null,
Accept: "*/*", //NOTE: Default Accept value sometimes gives error 406 on some clients
};
const {
headers = {},
method = "get", //Default initialization method type
url = "", //Default URL to hit
baseURL = process.env.REACT_APP_API_HOST, //Base url ex - in .env file
params = {}, //Default extra params
data = {}, //Default data to send
} = requestData;
//create request config according to data
const requestConfig = {
headers: Object.assign(defaultHeader, headers),
method,
url,
baseURL,
params,
paramsSerializer: (params) => {
return qs.stringify(params, { arrayFormat: "comma" });
},
data, //POST request data to send
};
try {
const response = await axios(requestConfig);
const limit = response.headers["x-collection-range"]; //For pagination
if (limit) {
const total = limit?.split("/")[1]; //For pagination purposes
return { data: response.data, total };
}
return { data: response.data }; //Success API response based on API endpoints
} catch (error) {
const { response: { status, data } = {} } = error || {}; //Based on ur API endpoints
if (status === 401) { //Handle API codes as necessary
dispatch(logout()); // Use hooks to handle Logout or redirection or anything
} else if (status === 404) {
window.location.replace("/not-found"); //Redirect to any page via hooks or window object.
} else {
alert(`${data.message}`); //Show notifications or alerts from 1 place instead of repetitive code
}
return data;
}
};
Extra axios integrations
Also adding additional performance metric tools like Firebase Performance Monitoring with Axios can also be easily setup with this.
This content originally appeared on DEV Community and was authored by Rahul Kasana
Rahul Kasana | Sciencx (2021-12-14T14:14:29+00:00) Axios HOC for React/React Native Apps – Code Enhancements. Retrieved from https://www.scien.cx/2021/12/14/axios-hoc-for-react-react-native-apps-code-enhancements/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.