Table Of Contents
Problem
You need a feature-rich HTTP client for Node.js with automatic JSON parsing, request/response interceptors, timeout handling, and better error management than the basic fetch() API.
Solution
const axios = require('axios');
// 1. Basic GET Request
async function basicGet() {
try {
const response = await axios.get('https://jsonplaceholder.typicode.com/posts/1');
console.log('Status:', response.status);
console.log('Headers:', response.headers);
console.log('Data:', response.data); // Automatically parsed JSON
return response.data;
} catch (error) {
console.error('GET error:', error.message);
throw error;
}
}
// 2. POST Request with JSON Data
async function postData(postData) {
try {
const response = await axios.post('https://jsonplaceholder.typicode.com/posts', postData, {
headers: {
'Content-Type': 'application/json',
'User-Agent': 'MyApp/1.0'
}
});
console.log('Created post:', response.data);
return response.data;
} catch (error) {
console.error('POST error:', error.response?.data || error.message);
throw error;
}
}
// 3. Axios Instance with Base Configuration
const apiClient = axios.create({
baseURL: 'https://jsonplaceholder.typicode.com',
timeout: 5000,
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
});
// Using the configured instance
async function useApiClient() {
try {
const response = await apiClient.get('/posts/1');
return response.data;
} catch (error) {
console.error('API client error:', error.message);
throw error;
}
}
// 4. Request and Response Interceptors
apiClient.interceptors.request.use(
(config) => {
// Add auth token to requests
const token = process.env.API_TOKEN;
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
console.log(`Making ${config.method?.toUpperCase()} request to ${config.url}`);
return config;
},
(error) => {
console.error('Request interceptor error:', error);
return Promise.reject(error);
}
);
apiClient.interceptors.response.use(
(response) => {
console.log(`Response received: ${response.status} ${response.statusText}`);
return response;
},
(error) => {
if (error.response?.status === 401) {
console.error('Unauthorized request - token may be invalid');
}
console.error('Response interceptor error:', error.response?.status);
return Promise.reject(error);
}
);
// 5. Multiple Request Methods
async function allHttpMethods() {
const baseUrl = 'https://jsonplaceholder.typicode.com';
try {
// GET
const getResponse = await axios.get(`${baseUrl}/posts/1`);
// POST
const postResponse = await axios.post(`${baseUrl}/posts`, {
title: 'New Post',
body: 'Post content',
userId: 1
});
// PUT
const putResponse = await axios.put(`${baseUrl}/posts/1`, {
id: 1,
title: 'Updated Post',
body: 'Updated content',
userId: 1
});
// PATCH
const patchResponse = await axios.patch(`${baseUrl}/posts/1`, {
title: 'Patched Title'
});
// DELETE
const deleteResponse = await axios.delete(`${baseUrl}/posts/1`);
return {
get: getResponse.data,
post: postResponse.data,
put: putResponse.data,
patch: patchResponse.data,
delete: deleteResponse.status
};
} catch (error) {
console.error('HTTP methods error:', error.message);
throw error;
}
}
// 6. Form Data and File Upload
const FormData = require('form-data');
const fs = require('fs');
async function uploadFile(filePath, additionalData) {
try {
const formData = new FormData();
formData.append('file', fs.createReadStream(filePath));
formData.append('description', additionalData.description);
formData.append('category', additionalData.category);
const response = await axios.post('https://httpbin.org/post', formData, {
headers: {
...formData.getHeaders(), // Important for multipart/form-data
},
maxContentLength: Infinity,
maxBodyLength: Infinity
});
return response.data;
} catch (error) {
console.error('Upload error:', error.message);
throw error;
}
}
// 7. Request Cancellation
async function cancellableRequest() {
const controller = new AbortController();
// Cancel request after 3 seconds
setTimeout(() => {
controller.abort();
}, 3000);
try {
const response = await axios.get('https://httpbin.org/delay/5', {
signal: controller.signal
});
return response.data;
} catch (error) {
if (axios.isCancel(error)) {
console.log('Request was cancelled');
throw new Error('Request cancelled by user');
}
throw error;
}
}
// 8. Concurrent Requests
async function concurrentRequests() {
try {
const requests = [
axios.get('https://jsonplaceholder.typicode.com/posts/1'),
axios.get('https://jsonplaceholder.typicode.com/posts/2'),
axios.get('https://jsonplaceholder.typicode.com/posts/3')
];
const responses = await Promise.allSettled(requests);
return responses.map((response, index) => {
if (response.status === 'fulfilled') {
return {
success: true,
data: response.value.data
};
} else {
return {
success: false,
error: response.reason.message
};
}
});
} catch (error) {
console.error('Concurrent requests error:', error.message);
throw error;
}
}
// 9. Retry Logic with Axios
async function axiosWithRetry(url, options = {}, maxRetries = 3) {
let lastError;
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
console.log(`Attempt ${attempt} of ${maxRetries}`);
const response = await axios.get(url, options);
return response;
} catch (error) {
lastError = error;
// Don't retry on client errors (4xx)
if (error.response?.status >= 400 && error.response?.status < 500) {
throw error;
}
if (attempt === maxRetries) {
break;
}
// Exponential backoff
const delay = Math.pow(2, attempt - 1) * 1000;
console.log(`Retrying in ${delay}ms...`);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
throw lastError;
}
// 10. Comprehensive Error Handling
async function handleAxiosErrors(url) {
try {
const response = await axios.get(url);
return response.data;
} catch (error) {
if (error.response) {
// Server responded with error status
console.error('Response error:', {
status: error.response.status,
statusText: error.response.statusText,
data: error.response.data,
headers: error.response.headers
});
throw new Error(`HTTP ${error.response.status}: ${error.response.statusText}`);
} else if (error.request) {
// Request was made but no response received
console.error('Request error:', error.request);
throw new Error('No response received from server');
} else {
// Something else happened
console.error('Setup error:', error.message);
throw new Error(`Request setup error: ${error.message}`);
}
}
}
// 11. Custom Axios Configuration
const customAxios = axios.create({
baseURL: 'https://api.example.com',
timeout: 10000,
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
validateStatus: (status) => {
// Consider 2xx and 3xx as success
return status >= 200 && status < 400;
},
transformRequest: [
(data, headers) => {
// Transform request data
if (typeof data === 'object') {
return JSON.stringify(data);
}
return data;
}
],
transformResponse: [
(data) => {
// Transform response data
try {
return JSON.parse(data);
} catch (error) {
return data;
}
}
]
});
// Usage examples
async function runExamples() {
try {
// Basic GET
const getData = await basicGet();
console.log('Basic GET:', getData.title);
// POST request
const postResult = await postData({
title: 'My Axios Post',
body: 'Content created with Axios',
userId: 1
});
console.log('POST result:', postResult.id);
// Multiple HTTP methods
const allMethods = await allHttpMethods();
console.log('All methods completed');
// Concurrent requests
const concurrent = await concurrentRequests();
console.log('Concurrent requests:', concurrent.length);
// Retry logic
const retryResult = await axiosWithRetry('https://httpbin.org/status/500');
console.log('Retry result:', retryResult.status);
} catch (error) {
console.error('Example error:', error.message);
}
}
// Install axios first: npm install axios
if (require.main === module) {
runExamples();
}
module.exports = {
basicGet,
postData,
apiClient,
uploadFile,
cancellableRequest,
concurrentRequests,
axiosWithRetry,
handleAxiosErrors
};
Install Axios:
npm install axios
# For form data uploads
npm install form-data
Explanation
Axios is a feature-rich HTTP client that automatically parses JSON responses and provides better error handling than fetch(). It supports request/response interceptors for adding authentication, logging, and error handling globally.
Create axios instances with axios.create()
for different APIs with their own base URLs and headers. Axios provides built-in support for request cancellation, timeouts, and concurrent requests with comprehensive error objects containing request/response details.
Share this article
Add Comment
No comments yet. Be the first to comment!