Spaces:
Sleeping
Sleeping
API Migration Guide: Moving to Centralized Axios Implementation
Why Migrate?
Our project has implemented a new centralized API client using Axios interceptors which provides:
- Centralized error handling: Errors are handled consistently across all API calls
- Standardized response format: All API responses follow the same format
- Authentication: Automatic token management
- Retries and token refresh: Automatic token refresh for expired tokens
- Progress tracking: Built-in progress tracking for file uploads
- Reduced code duplication: No need to repeat the same error handling everywhere
- Easier debugging: All API requests go through the same pipeline, making it easier to debug
Migration Steps
1. Update Imports
Replace direct Axios imports with our utility functions:
// OLD
import axios from 'axios';
import { API_BASE_URL } from '../config';
// NEW
import { get, getList, post, put, patch, del, uploadFile } from '../lib/api/api-utils';
2. Remove API_BASE_URL from Service URLs
The base URL is already configured in the Axios instance, so you should:
// OLD
private baseUrl = `${API_BASE_URL}/api/users`;
// NEW
private baseUrl = `/api/users`;
3. Replace Direct Axios Calls
Replace direct Axios calls with our utility functions:
GET Requests
// OLD
async getItem(id: number): Promise<ResponseData<Item>> {
try {
const response = await axios.get(`${this.baseUrl}/${id}`);
return {
data: response.data,
success: true,
message: 'Item fetched successfully'
};
} catch (error: any) {
return {
data: {} as Item,
success: false,
message: error.message || 'Failed to fetch item'
};
}
}
// NEW
async getItem(id: number): Promise<ResponseData<Item>> {
return get<Item>(`${this.baseUrl}/${id}`);
}
GET List Requests
// OLD
async getItems(): Promise<ResponseData<Item[]>> {
try {
const response = await axios.get(this.baseUrl);
return {
data: response.data,
success: true,
message: 'Items fetched successfully'
};
} catch (error: any) {
return {
data: [],
success: false,
message: error.message || 'Failed to fetch items'
};
}
}
// NEW
async getItems(): Promise<ResponseData<Item[]>> {
return getList<Item>(this.baseUrl);
}
POST Requests
// OLD
async createItem(item: ItemCreateRequest): Promise<ResponseData<Item>> {
try {
const response = await axios.post(this.baseUrl, item, {
headers: { 'Content-Type': 'application/json' }
});
return {
data: response.data,
success: true,
message: 'Item created successfully'
};
} catch (error: any) {
return {
data: {} as Item,
success: false,
message: error.message || 'Failed to create item'
};
}
}
// NEW
async createItem(item: ItemCreateRequest): Promise<ResponseData<Item>> {
return post<Item, ItemCreateRequest>(this.baseUrl, item);
}
PUT Requests
// OLD
async updateItem(item: ItemUpdateRequest): Promise<ResponseData<Item>> {
try {
const response = await axios.put(`${this.baseUrl}/${item.id}`, item, {
headers: { 'Content-Type': 'application/json' }
});
return {
data: response.data,
success: true,
message: 'Item updated successfully'
};
} catch (error: any) {
return {
data: {} as Item,
success: false,
message: error.message || 'Failed to update item'
};
}
}
// NEW
async updateItem(item: ItemUpdateRequest): Promise<ResponseData<Item>> {
return put<Item, ItemUpdateRequest>(`${this.baseUrl}/${item.id}`, item);
}
DELETE Requests
// OLD
async deleteItem(id: number): Promise<ResponseData<boolean>> {
try {
await axios.delete(`${this.baseUrl}/${id}`);
return {
data: true,
success: true,
message: 'Item deleted successfully'
};
} catch (error: any) {
return {
data: false,
success: false,
message: error.message || 'Failed to delete item'
};
}
}
// NEW
async deleteItem(id: number): Promise<ResponseData<boolean>> {
return del(`${this.baseUrl}/${id}`);
}
File Uploads
// OLD
async uploadFile(file: File, metadata: any): Promise<ResponseData<Document>> {
try {
const formData = new FormData();
formData.append('file', file);
formData.append('metadata', JSON.stringify(metadata));
const response = await axios.post(`${this.baseUrl}/upload`, formData, {
headers: { 'Content-Type': 'multipart/form-data' },
onUploadProgress: (progressEvent) => {
// Handle progress
}
});
return {
data: response.data,
success: true,
message: 'File uploaded successfully'
};
} catch (error: any) {
return {
data: {} as Document,
success: false,
message: error.message || 'Failed to upload file'
};
}
}
// NEW
async uploadDocument(file: File, metadata: any): Promise<ResponseData<Document>> {
return uploadFile<Document>(
`${this.baseUrl}/upload`,
file,
{ metadata: JSON.stringify(metadata) },
(progress) => {
// Handle progress
console.log(`Upload progress: ${progress}%`);
}
);
}
Testing Your Migration
- Ensure you have migrated all API calls in a service
- Test the functionality to verify it works as expected
- Confirm that authentication, error handling, and response formatting work correctly
Need Help?
If you have any questions about the migration process, please refer to the full documentation in src/lib/api/README.md or contact the development team.