pmtool / API-MIGRATION-GUIDE.md
devarshia5's picture
Upload 487 files
d97b8f9 verified
|
Raw
History Blame Contribute Delete
5.99 kB

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

  1. Ensure you have migrated all API calls in a service
  2. Test the functionality to verify it works as expected
  3. 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.