Chapter 2: Detailed HTTP Request Methods
Haiyue
23min
Chapter 2: Detailed HTTP Request Methods
Learning Objectives
- Master the usage of GET requests
- Learn to send data with POST requests
- Understand PUT, PATCH, DELETE and other methods
- Master parameter passing methods
- Learn to handle different 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 resources",
crud: "Read",
idempotent: true,
safe: true,
examples: ["Get user list", "View article details", "Search products"]
},
POST: {
purpose: "Create resources",
crud: "Create",
idempotent: false,
safe: false,
examples: ["Register user", "Publish article", "Submit order"]
},
PUT: {
purpose: "Complete update of resource",
crud: "Update",
idempotent: true,
safe: false,
examples: ["Update user info", "Replace article content"]
},
PATCH: {
purpose: "Partial update of resource",
crud: "Update",
idempotent: false,
safe: false,
examples: ["Modify user avatar", "Update article title"]
},
DELETE: {
purpose: "Delete resources",
crud: "Delete",
idempotent: true,
safe: false,
examples: ["Delete user", "Delete article", "Cancel order"]
}
};
All Methods Supported by Axios
// Convenient 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 GET Requests Explained
Basic GET Request
// Simplest GET request
async function basicGetRequest() {
try {
const response = await axios.get('https://jsonplaceholder.typicode.com/posts');
console.log('Retrieved articles:', response.data.slice(0, 3)); // Show only first 3
return response.data;
} catch (error) {
console.error('GET request failed:', error);
throw error;
}
}
GET Request with Parameters
// Method 1: URL parameter concatenation
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 params configuration
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: Dynamic parameter building
async function getWithDynamicParams(filters) {
const params = {};
// Add parameters dynamically 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('Results:', 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 header info:', response.config.headers);
console.log('Response data:', response.data);
return response.data;
}
// GET request with 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('Got data before timeout:', response.data.length);
return response.data;
} catch (error) {
if (error.code === 'ECONNABORTED') {
console.error('Request timeout');
}
throw error;
}
}
2.3 POST Requests Explained
Sending JSON Data
// Send JSON format data
async function postJsonData() {
const postData = {
title: 'New Article Title',
body: 'This is the article content',
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('Created successfully:', response.data);
console.log('Status code:', response.status);
return response.data;
} catch (error) {
console.error('POST request failed:', error);
throw error;
}
}
Sending Form Data
// Send form format data (application/x-www-form-urlencoded)
async function postFormData() {
const formData = new URLSearchParams();
formData.append('title', 'Form Submitted Title');
formData.append('body', 'Form Submitted Content');
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 qs library to handle complex form data
const qs = require('qs'); // Need to install: 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 File and Multimedia Data
// Send FormData (for file uploads)
async function postWithFormData() {
const formData = new FormData();
// Add text fields
formData.append('title', 'Article with Files');
formData.append('description', 'This article contains images');
// Add file (in 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 - Complete Resource Replacement
// PUT request for complete resource update
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 - Partial Resource Update
// PATCH request for partial resource update
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 completed:', responses.length);
return responses.map(response => response.data);
} catch (error) {
console.error('Batch update failed:', error);
throw error;
}
}
2.5 DELETE Requests
Basic DELETE Request
// Delete 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 requests usually return 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 confirmed:', 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 the resource info 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 actual projects, this would be a dialog confirmation)
const confirmed = true; // Should actually 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 cancelled deletion');
return false;
}
} catch (error) {
console.error('Deletion operation failed:', error);
throw error;
}
}
Batch Deletion
// 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 completed: ${successful.length} successful, ${failed.length} failed`);
if (failed.length > 0) {
console.log('Failed deletion IDs:', failed.map(f => f.id));
}
return { successful, failed };
} catch (error) {
console.error('Batch deletion operation failed:', error);
throw error;
}
}
// Soft delete (logical deletion)
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 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 to get server-supported HTTP methods
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 header info:', {
'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 Conversion
// 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 JavaScript objects to JSON strings
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 response
if (typeof data === 'object' && data !== null) {
// Add 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 Practice 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 single user
async getUser(id) {
const response = await axios.get(`${this.baseURL}/users/${id}`);
return response.data;
}
// Create user
async createUser(userData) {
const response = await axios.post(`${this.baseURL}/users`, userData);
return response.data;
}
// Complete update user
async updateUser(id, userData) {
const response = await axios.put(`${this.baseURL}/users/${id}`, userData);
return response.data;
}
// Partial update user
async patchUser(id, partialData) {
const response = await axios.patch(`${this.baseURL}/users/${id}`, partialData);
return response.data;
}
// Delete 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('=== Getting all users ===');
const users = await userAPI.getUsers();
console.log(`Found ${users.length} users`);
// Get specific user
console.log('=== Getting user details ===');
const user = await userAPI.getUser(1);
console.log('User info:', user.name, user.email);
// Create new user
console.log('=== Creating new user ===');
const newUser = await userAPI.createUser({
name: 'Test User',
username: 'testuser',
email: 'test@example.com'
});
console.log('New user:', newUser);
// Update user
console.log('=== Updating user info ===');
const updatedUser = await userAPI.patchUser(1, {
email: 'newemail@example.com'
});
console.log('After update:', updatedUser);
// Get user posts
console.log('=== Getting user 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 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 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:
- HTTP Methods Overview: Understood the purpose and characteristics of different HTTP methods
- GET Requests: Mastered parameter passing, header setting, timeout control and other techniques
- POST Requests: Learned to send data in different formats such as JSON, forms, and files
- PUT/PATCH Requests: Understood the difference and application between complete update and partial update
- 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 actual projects.
Key Points
- GET requests are for getting data, parameters are passed via URL or params
- POST requests are for creating resources, data is in the request body
- PUT is for complete replacement, PATCH is for partial updates
- DELETE is for deleting resources, can be physical or logical deletion
- Choosing the right HTTP method makes APIs more RESTful and semantic
- Proper data format handling is key to API interaction
Next Chapter Preview
The next chapter will learn about request and response configuration, including advanced configuration techniques such as request header management, timeout settings, and response handling.