Chapter 2: Detailed HTTP Request Methods
9/1/25About 8 min
Chapter 2: Detailed HTTP Request Methods
Learning Objectives
- Master the usage of GET requests
- Learn to send data with POST requests
- Understand methods like PUT, PATCH, and DELETE
- Master different ways to pass request parameters
- Learn to handle various data formats
2.1 Overview of HTTP Methods
HTTP Methods in REST Architecture
// Mapping of HTTP methods to CRUD operations
const httpMethodMapping = {
GET: {
purpose: "Read resource",
crud: "Read",
idempotent: true,
safe: true,
examples: ["Get user list", "View article details", "Search for products"]
},
POST: {
purpose: "Create resource",
crud: "Create",
idempotent: false,
safe: false,
examples: ["Register user", "Publish article", "Submit order"]
},
PUT: {
purpose: "Fully update resource",
crud: "Update",
idempotent: true,
safe: false,
examples: ["Update user information", "Replace article content"]
},
PATCH: {
purpose: "Partially update resource",
crud: "Update",
idempotent: false,
safe: false,
examples: ["Change user avatar", "Update article title"]
},
DELETE: {
purpose: "Delete resource",
crud: "Delete",
idempotent: true,
safe: false,
examples: ["Delete user", "Delete article", "Cancel order"]
}
};
All Methods Supported by Axios
// Convenience methods provided by Axios
const axiosMethods = {
'axios.request(config)': 'Generic request method',
'axios.get(url[, config])': 'GET request',
'axios.delete(url[, config])': 'DELETE request',
'axios.head(url[, config])': 'HEAD request',
'axios.options(url[, config])': 'OPTIONS request',
'axios.post(url[, data[, config]])': 'POST request',
'axios.put(url[, data[, config]])': 'PUT request',
'axios.patch(url[, data[, config]])': 'PATCH request'
};
2.2 Detailed GET Requests
Basic GET Request
// Simplest GET request
async function basicGetRequest() {
try {
const response = await axios.get('https://jsonplaceholder.typicode.com/posts');
console.log('Fetched articles:', response.data.slice(0, 3)); // Show only the first 3
return response.data;
} catch (error) {
console.error('GET request failed:', error);
throw error;
}
}
GET Request with Parameters
// Method 1: Appending parameters to the URL
async function getWithUrlParams() {
const url = 'https://jsonplaceholder.typicode.com/posts?userId=1&_limit=5';
const response = await axios.get(url);
console.log('URL parameters method:', response.data);
return response.data;
}
// Method 2: Using the `params` config
async function getWithParamsConfig() {
const response = await axios.get('https://jsonplaceholder.typicode.com/posts', {
params: {
userId: 1,
_limit: 5,
_sort: 'id',
_order: 'desc'
}
});
console.log('`params` config method:', response.data);
return response.data;
}
// Method 3: Dynamically building parameters
async function getWithDynamicParams(filters) {
const params = {};
// Dynamically add parameters based on conditions
if (filters.userId) params.userId = filters.userId;
if (filters.limit) params._limit = filters.limit;
if (filters.search) params.q = filters.search;
const response = await axios.get('https://jsonplaceholder.typicode.com/posts', {
params
});
console.log('Dynamic parameters:', params);
console.log('Result:', response.data);
return response.data;
}
Advanced GET Request Usage
// GET request with headers
async function getWithHeaders() {
const response = await axios.get('https://jsonplaceholder.typicode.com/posts/1', {
headers: {
'Accept': 'application/json',
'User-Agent': 'MyApp/1.0',
'Authorization': 'Bearer your-token-here'
}
});
console.log('Request headers:', response.config.headers);
console.log('Response data:', response.data);
return response.data;
}
// GET request with a timeout
async function getWithTimeout() {
try {
const response = await axios.get('https://jsonplaceholder.typicode.com/posts', {
timeout: 5000, // 5-second timeout
params: {
_limit: 10
}
});
console.log('Data fetched before timeout:', response.data.length);
return response.data;
} catch (error) {
if (error.code === 'ECONNABORTED') {
console.error('Request timed out');
}
throw error;
}
}
2.3 Detailed POST Requests
Sending JSON Data
// Sending JSON formatted data
async function postJsonData() {
const postData = {
title: 'New Article Title',
body: 'This is the content of the article',
userId: 1,
tags: ['javascript', 'axios', 'http'],
publishedAt: new Date().toISOString()
};
try {
const response = await axios.post('https://jsonplaceholder.typicode.com/posts', postData, {
headers: {
'Content-Type': 'application/json'
}
});
console.log('Creation successful:', response.data);
console.log('Status code:', response.status);
return response.data;
} catch (error) {
console.error('POST request failed:', error);
throw error;
}
}
Sending Form Data
// Sending form data (application/x-www-form-urlencoded)
async function postFormData() {
const formData = new URLSearchParams();
formData.append('title', 'Title submitted via form');
formData.append('body', 'Content submitted via form');
formData.append('userId', '1');
try {
const response = await axios.post('https://jsonplaceholder.typicode.com/posts', formData, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
});
console.log('Form submission successful:', response.data);
return response.data;
} catch (error) {
console.error('Form submission failed:', error);
throw error;
}
}
// Using the qs library to handle complex form data
const qs = require('qs'); // Requires installation: npm install qs
async function postComplexFormData() {
const data = {
user: {
name: 'Zhang San',
email: 'zhangsan@example.com',
preferences: ['news', 'sports', 'technology']
},
settings: {
theme: 'dark',
notifications: true
}
};
const formData = qs.stringify(data);
const response = await axios.post('/api/user/profile', formData, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
});
return response.data;
}
Sending Files and Multimedia Data
// Sending FormData (for file uploads)
async function postWithFormData() {
const formData = new FormData();
// Add text fields
formData.append('title', 'Article with a file');
formData.append('description', 'This article contains an image');
// Add a file (in a browser environment)
const fileInput = document.getElementById('file-input');
if (fileInput && fileInput.files[0]) {
formData.append('image', fileInput.files[0]);
}
// Can also add Blob data
const blob = new Blob(['Hello World'], { type: 'text/plain' });
formData.append('textFile', blob, 'hello.txt');
try {
const response = await axios.post('/api/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
});
console.log('File upload successful:', response.data);
return response.data;
} catch (error) {
console.error('File upload failed:', error);
throw error;
}
}
2.4 PUT and PATCH Requests
PUT Request - Fully Replace Resource
// PUT request is used to fully update a resource
async function updateUserWithPUT() {
const userId = 1;
const completeUserData = {
id: userId,
name: 'Li Si',
username: 'lisi',
email: 'lisi@example.com',
address: {
street: 'New Street',
suite: 'Apt. 556',
city: 'Beijing',
zipcode: '100000',
geo: {
lat: '39.9042',
lng: '116.4074'
}
},
phone: '1-770-736-8031',
website: 'lisi.org',
company: {
name: 'New Company',
catchPhrase: 'Innovative Technology',
bs: 'harness real-time e-markets'
}
};
try {
const response = await axios.put(
`https://jsonplaceholder.typicode.com/users/${userId}`,
completeUserData
);
console.log('PUT update successful:', response.data);
console.log('Status code:', response.status);
return response.data;
} catch (error) {
console.error('PUT update failed:', error);
throw error;
}
}
PATCH Request - Partially Update Resource
// PATCH request is used to partially update a resource
async function updateUserWithPATCH() {
const userId = 1;
const partialUpdate = {
name: 'Wang Wu',
email: 'wangwu@example.com'
// Only update these two fields, other fields remain unchanged
};
try {
const response = await axios.patch(
`https://jsonplaceholder.typicode.com/users/${userId}`,
partialUpdate
);
console.log('PATCH update successful:', response.data);
return response.data;
} catch (error) {
console.error('PATCH update failed:', error);
throw error;
}
}
// Batch PATCH update
async function batchUpdateUsers() {
const updates = [
{ id: 1, email: 'user1@newdomain.com' },
{ id: 2, email: 'user2@newdomain.com' },
{ id: 3, email: 'user3@newdomain.com' }
];
try {
const promises = updates.map(update =>
axios.patch(`https://jsonplaceholder.typicode.com/users/${update.id}`, {
email: update.email
})
);
const responses = await Promise.all(promises);
console.log('Batch update complete:', responses.length);
return responses.map(response => response.data);
} catch (error) {
console.error('Batch update failed:', error);
throw error;
}
}
2.5 DELETE Request
Basic DELETE Request
// Delete a single resource
async function deleteUser(userId) {
try {
const response = await axios.delete(
`https://jsonplaceholder.typicode.com/users/${userId}`
);
console.log('Deletion successful, status code:', response.status);
// DELETE request usually returns 204 No Content or 200 OK
if (response.status === 204) {
console.log('Resource deleted, no content returned');
} else if (response.status === 200) {
console.log('Deletion confirmation:', response.data);
}
return true;
} catch (error) {
console.error(`Failed to delete user ${userId}:`, error);
throw error;
}
}
// Delete with confirmation
async function deleteWithConfirmation(userId) {
try {
// First, get information about the resource to be deleted
const userResponse = await axios.get(
`https://jsonplaceholder.typicode.com/users/${userId}`
);
const user = userResponse.data;
console.log(`Preparing to delete user: ${user.name} (${user.email})`);
// Simulate user confirmation (in a real project, this might be a confirmation dialog)
const confirmed = true; // Should be the result of user interaction
if (confirmed) {
await axios.delete(`https://jsonplaceholder.typicode.com/users/${userId}`);
console.log('User deleted successfully');
return true;
} else {
console.log('User canceled the delete operation');
return false;
}
} catch (error) {
console.error('Delete operation failed:', error);
throw error;
}
}
Batch Delete
// Batch delete multiple resources
async function batchDeleteUsers(userIds) {
try {
const deletePromises = userIds.map(id =>
axios.delete(`https://jsonplaceholder.typicode.com/users/${id}`)
.then(() => ({ id, success: true }))
.catch(error => ({ id, success: false, error: error.message }))
);
const results = await Promise.all(deletePromises);
const successful = results.filter(r => r.success);
const failed = results.filter(r => !r.success);
console.log(`Deletion complete: ${successful.length} successful, ${failed.length} failed`);
if (failed.length > 0) {
console.log('Failed to delete IDs:', failed.map(f => f.id));
}
return { successful, failed };
} catch (error) {
console.error('Batch delete operation failed:', error);
throw error;
}
}
// Soft delete (logical delete)
async function softDeleteUser(userId) {
try {
const response = await axios.patch(
`https://jsonplaceholder.typicode.com/users/${userId}`,
{
deleted: true,
deletedAt: new Date().toISOString()
}
);
console.log('Soft delete successful:', response.data);
return response.data;
} catch (error) {
console.error('Soft delete failed:', error);
throw error;
}
}
2.6 Other HTTP Methods
HEAD Request
// HEAD request only gets response headers, not the response body
async function headRequest() {
try {
const response = await axios.head('https://jsonplaceholder.typicode.com/posts/1');
console.log('HEAD request successful');
console.log('Status code:', response.status);
console.log('Response headers:', response.headers);
console.log('Content length:', response.headers['content-length']);
console.log('Content type:', response.headers['content-type']);
console.log('Response body:', response.data); // Should be empty
return response.headers;
} catch (error) {
console.error('HEAD request failed:', error);
throw error;
}
}
OPTIONS Request
// OPTIONS request is used to get the HTTP methods supported by the server
async function optionsRequest() {
try {
const response = await axios.options('https://jsonplaceholder.typicode.com/posts');
console.log('OPTIONS request successful');
console.log('Allowed methods:', response.headers['allow']);
console.log('CORS headers:', {
'Access-Control-Allow-Origin': response.headers['access-control-allow-origin'],
'Access-Control-Allow-Methods': response.headers['access-control-allow-methods'],
'Access-Control-Allow-Headers': response.headers['access-control-allow-headers']
});
return response.headers;
} catch (error) {
console.error('OPTIONS request failed:', error);
throw error;
}
}
2.7 Request Data Format Handling
Automatic Data Transformation
// Axios automatically handles common data formats
const dataFormatExamples = {
// JSON data (default)
json: async () => {
const data = { name: 'John', age: 30 };
const response = await axios.post('/api/users', data);
// Axios automatically sets Content-Type to application/json
// and converts the JavaScript object to a JSON string
return response.data;
},
// String data
string: async () => {
const data = 'plain text data';
const response = await axios.post('/api/text', data, {
headers: { 'Content-Type': 'text/plain' }
});
return response.data;
},
// ArrayBuffer data
arrayBuffer: async () => {
const buffer = new ArrayBuffer(1024);
const response = await axios.post('/api/binary', buffer, {
headers: { 'Content-Type': 'application/octet-stream' }
});
return response.data;
}
};
Custom Data Transformation
// Custom request data transformer
const customTransformRequest = [
function(data, headers) {
// Transform data before sending
if (typeof data === 'object' && data !== null) {
// Custom JSON serialization
return JSON.stringify(data, null, 2);
}
return data;
},
...axios.defaults.transformRequest // Keep default transformers
];
// Custom response data transformer
const customTransformResponse = [
...axios.defaults.transformResponse, // Keep default transformers
function(data) {
// Transform data after processing the response
if (typeof data === 'object' && data !== null) {
// Add a timestamp
data._receivedAt = new Date().toISOString();
}
return data;
}
];
// Using custom transformers
async function requestWithCustomTransform() {
const response = await axios.post('/api/data',
{ message: 'Hello World' },
{
transformRequest: customTransformRequest,
transformResponse: customTransformResponse
}
);
console.log('Transformed data:', response.data);
return response.data;
}
2.8 Practical Exercises
Exercise 1: User Management API
// Complete user management API wrapper
class UserAPI {
constructor(baseURL = 'https://jsonplaceholder.typicode.com') {
this.baseURL = baseURL;
}
// Get all users
async getUsers(params = {}) {
const response = await axios.get(`${this.baseURL}/users`, { params });
return response.data;
}
// Get a single user
async getUser(id) {
const response = await axios.get(`${this.baseURL}/users/${id}`);
return response.data;
}
// Create a user
async createUser(userData) {
const response = await axios.post(`${this.baseURL}/users`, userData);
return response.data;
}
// Fully update a user
async updateUser(id, userData) {
const response = await axios.put(`${this.baseURL}/users/${id}`, userData);
return response.data;
}
// Partially update a user
async patchUser(id, partialData) {
const response = await axios.patch(`${this.baseURL}/users/${id}`, partialData);
return response.data;
}
// Delete a user
async deleteUser(id) {
const response = await axios.delete(`${this.baseURL}/users/${id}`);
return response.status === 200;
}
// Get user's posts
async getUserPosts(userId) {
const response = await axios.get(`${this.baseURL}/posts`, {
params: { userId }
});
return response.data;
}
}
// Usage example
async function testUserAPI() {
const userAPI = new UserAPI();
try {
// Get all users
console.log('=== Get All Users ===');
const users = await userAPI.getUsers();
console.log(`Found ${users.length} users`);
// Get a specific user
console.log('=== Get User Details ===');
const user = await userAPI.getUser(1);
console.log('User info:', user.name, user.email);
// Create a new user
console.log('=== Create New User ===');
const newUser = await userAPI.createUser({
name: 'Test User',
username: 'testuser',
email: 'test@example.com'
});
console.log('New user:', newUser);
// Update a user
console.log('=== Update User Info ===');
const updatedUser = await userAPI.patchUser(1, {
email: 'newemail@example.com'
});
console.log('Updated:', updatedUser);
// Get user's posts
console.log("=== Get User's Posts ===");
const posts = await userAPI.getUserPosts(1);
console.log(`User has ${posts.length} posts`);
} catch (error) {
console.error('API test failed:', error);
}
}
testUserAPI();
Exercise 2: Product Management System
// E-commerce product management API
class ProductAPI {
constructor(baseURL = '/api') {
this.baseURL = baseURL;
}
// Get product list (supports search, pagination, sorting)
async getProducts(options = {}) {
const {
search = '',
category = '',
page = 1,
limit = 20,
sortBy = 'createdAt',
order = 'desc',
minPrice,
maxPrice
} = options;
const params = {
page,
limit,
sortBy,
order
};
if (search) params.search = search;
if (category) params.category = category;
if (minPrice !== undefined) params.minPrice = minPrice;
if (maxPrice !== undefined) params.maxPrice = maxPrice;
const response = await axios.get(`${this.baseURL}/products`, { params });
return response.data;
}
// Create a product
async createProduct(productData) {
const response = await axios.post(`${this.baseURL}/products`, productData);
return response.data;
}
// Batch create products
async batchCreateProducts(productsArray) {
const response = await axios.post(`${this.baseURL}/products/batch`, {
products: productsArray
});
return response.data;
}
// Update product stock
async updateStock(productId, quantity, operation = 'set') {
const response = await axios.patch(`${this.baseURL}/products/${productId}/stock`, {
quantity,
operation // 'set', 'add', 'subtract'
});
return response.data;
}
// Upload product image
async uploadProductImage(productId, imageFile) {
const formData = new FormData();
formData.append('image', imageFile);
formData.append('productId', productId);
const response = await axios.post(`${this.baseURL}/products/${productId}/images`, formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
});
return response.data;
}
// Delete a product (soft delete)
async deleteProduct(productId, permanent = false) {
if (permanent) {
const response = await axios.delete(`${this.baseURL}/products/${productId}?permanent=true`);
return response.data;
} else {
const response = await axios.patch(`${this.baseURL}/products/${productId}`, {
deleted: true,
deletedAt: new Date().toISOString()
});
return response.data;
}
}
}
Chapter Summary
In Chapter 2, we learned in-depth about:
- HTTP Method Overview: Understood the purpose and characteristics of different HTTP methods.
- GET Requests: Mastered parameter passing, header settings, and timeout control.
- POST Requests: Learned to send data in different formats like JSON, form, and file.
- PUT/PATCH Requests: Understood the difference and application of full and partial updates.
- DELETE Requests: Mastered various scenarios and best practices for resource deletion.
- Other Methods: Learned the purpose of auxiliary methods like HEAD and OPTIONS.
- Data Formats: Learned to handle various request and response data formats.
This knowledge provides a solid foundation for flexibly using Axios to handle various HTTP communication needs in real projects.
Key Takeaways
- GET requests are for fetching data, with parameters passed via URL or
params
. - POST requests are for creating resources, with data in the request body.
- PUT is for full replacement, PATCH is for partial updates.
- DELETE is for deleting resources, which can be physical or logical deletion.
- Choosing the correct HTTP method makes APIs more RESTful and semantic.
- Correct handling of data formats is key to API interaction.
Next Chapter Preview
The next chapter will cover request and response configuration, including advanced configuration techniques like header management, timeout settings, and response handling.