Building Reusable API Utility Functions with Axios

blog thumbnail
nextreact
26 October 2024
In modern web development, working with APIs is a crucial part of creating dynamic, data-driven applications. To simplify and standardize API interactions, it's a common practice to create reusable functions for different HTTP methods. In this guide, we'll go through how to set up a set of utility functions for making GET, POST, PUT, DELETE, and PATCH requests using Axios, a popular JavaScript library for HTTP requests.

Why Use Axios?

Axios is a versatile HTTP client for JavaScript that simplifies API requests and responses. Its promise-based design makes handling asynchronous operations straightforward, while automatic JSON parsing and serialization reduce manual work. Compatible with both browser and Node.js environments, Axios supports custom headers for authentication and configuration needs. Additionally, its built-in error handling ensures consistent responses, making it easier for developers to manage unexpected issues. These features collectively make Axios an excellent choice for building robust web applications.

The Code (TypeScript)

Below is our final set of utility functions, where each function represents a specific HTTP request type. These are flexible and reusable for any project using Axios.
Code
1import axios, { AxiosRequestConfig } from 'axios'; 2 3export async function apiGet(endpoint: string, params = {}, additionalHeaders = {}) { 4 try { 5 const response = await axios.get(endpoint, { 6 params, 7 headers: { 8 'Content-Type': 'application/json', 9 ...additionalHeaders, 10 }, 11 }); 12 return response.data; 13 } catch (error) { 14 console.error('API GET Error:', error); 15 throw error; 16 } 17} 18 19export async function apiPost(endpoint: string, body: any, isFormData = false, additionalHeaders = {}) { 20 try { 21 const headers = { 22 'Content-Type': isFormData ? 'multipart/form-data' : 'application/json', 23 ...additionalHeaders, 24 }; 25 26 const response = await axios.post(endpoint, isFormData ? body : JSON.stringify(body), { headers }); 27 return response.data; 28 } catch (error) { 29 console.error('API POST Error:', error); 30 throw error; 31 } 32} 33 34export async function apiPut(endpoint: string, body: any, additionalHeaders = {}) { 35 try { 36 const response = await axios.put(endpoint, JSON.stringify(body), { 37 headers: { 38 'Content-Type': 'application/json', 39 ...additionalHeaders, 40 }, 41 }); 42 return response.data; 43 } catch (error) { 44 console.error('API PUT Error:', error); 45 throw error; 46 } 47} 48 49export async function apiDelete(endpoint: string, body: any, additionalHeaders = {}) { 50 try { 51 const response = await axios.delete(endpoint, { 52 headers: { 53 'Content-Type': 'application/json', 54 ...additionalHeaders, 55 }, 56 data: JSON.stringify(body), 57 }); 58 return { success: true }; 59 } catch (error) { 60 console.error('API DELETE Error:', error); 61 throw error; 62 } 63} 64 65export async function apiPatch(endpoint: string, body: any, isFormData = false, additionalHeaders = {}) { 66 try { 67 const headers = { 68 'Content-Type': isFormData ? 'multipart/form-data' : 'application/json', 69 ...additionalHeaders, 70 }; 71 72 const response = await axios.patch(endpoint, isFormData ? body : JSON.stringify(body), { headers }); 73 return response.data; 74 } catch (error) { 75 console.error('API PATCH Error:', error); 76 throw error; 77 } 78}

The Code (JavaScript)

Below is our final set of utility functions, where each function represents a specific HTTP request type. These are flexible and reusable for any project using Axios.
Code
1import axios from 'axios'; 2 3export async function apiGet(endpoint, params = {}, additionalHeaders = {}) { 4 try { 5 const response = await axios.get(endpoint, { 6 params, 7 headers: { 8 'Content-Type': 'application/json', 9 ...additionalHeaders, 10 }, 11 }); 12 return response.data; 13 } catch (error) { 14 console.error('API GET Error:', error); 15 throw error; 16 } 17} 18 19export async function apiPost(endpoint, body, isFormData = false, additionalHeaders = {}) { 20 try { 21 const headers = { 22 'Content-Type': isFormData ? 'multipart/form-data' : 'application/json', 23 ...additionalHeaders, 24 }; 25 26 const response = await axios.post(endpoint, isFormData ? body : JSON.stringify(body), { headers }); 27 return response.data; 28 } catch (error) { 29 console.error('API POST Error:', error); 30 throw error; 31 } 32} 33 34export async function apiPut(endpoint, body, additionalHeaders = {}) { 35 try { 36 const response = await axios.put(endpoint, JSON.stringify(body), { 37 headers: { 38 'Content-Type': 'application/json', 39 ...additionalHeaders, 40 }, 41 }); 42 return response.data; 43 } catch (error) { 44 console.error('API PUT Error:', error); 45 throw error; 46 } 47} 48 49export async function apiDelete(endpoint, body, additionalHeaders = {}) { 50 try { 51 const response = await axios.delete(endpoint, { 52 headers: { 53 'Content-Type': 'application/json', 54 ...additionalHeaders, 55 }, 56 data: JSON.stringify(body), 57 }); 58 return { success: true }; 59 } catch (error) { 60 console.error('API DELETE Error:', error); 61 throw error; 62 } 63} 64 65export async function apiPatch(endpoint, body, isFormData = false, additionalHeaders = {}) { 66 try { 67 const headers = { 68 'Content-Type': isFormData ? 'multipart/form-data' : 'application/json', 69 ...additionalHeaders, 70 }; 71 72 const response = await axios.patch(endpoint, isFormData ? body : JSON.stringify(body), { headers }); 73 return response.data; 74 } catch (error) { 75 console.error('API PATCH Error:', error); 76 throw error; 77 } 78}

Using These Functions

Here’s a quick example of how you might use these functions:
Code
1// Example: Fetch data with GET 2try { 3 const data = await apiGet('https://api.example.com/users', { page: 1 }); 4 console.log(data); 5} catch (error) { 6 console.error('Error fetching users:', error); 7} 8 9// Example: Create a new user with POST 10try { 11 const newUser = { name: 'John Doe', email: 'johndoe@example.com' }; 12 const data = await apiPost('https://api.example.com/users', newUser); 13 console.log(data); 14} catch (error) { 15 console.error('Error creating user:', error); 16}

Conclusion

Creating a set of reusable API functions like this can streamline your code, improve error handling, and make it easier to handle various API requests consistently. With just a few lines of code, you’re now equipped to manage your API calls efficiently and flexibly across different projects.