Xử lý API Requests
Shared API Requests
Phần tiêu đề “Shared API Requests”Bắt đầu bằng cách đặt logic API request chung trong thư mục shared/api. Điều này giúp dễ dàng tái sử dụng các request trong toàn bộ ứng dụng và hỗ trợ prototyping nhanh hơn. Đối với nhiều dự án, đây là tất cả những gì bạn cần cho các API call.
Cấu trúc file điển hình sẽ là:
Thư mụcshared/
- client.ts
- index.ts
Thư mụcendpoints/
- login.ts
File client.ts tập trung thiết lập HTTP request của bạn. Nó bao bọc phương thức bạn chọn (như fetch() hoặc một instance axios) và xử lý các cấu hình chung, chẳng hạn như:
- Backend base URL.
- Default headers (ví dụ, cho authentication).
- Data serialization.
Dưới đây là các ví dụ cho axios và fetch:
// Example using axiosimport axios from 'axios';
export const client = axios.create({ baseURL: 'https://your-api-domain.com/api/', timeout: 5000, headers: { 'X-Custom-Header': 'my-custom-value' }});export const client = { async post(endpoint: string, body: any, options?: RequestInit) { const response = await fetch(`https://your-api-domain.com/api${endpoint}`, { method: 'POST', body: JSON.stringify(body), ...options, headers: { 'Content-Type': 'application/json', 'X-Custom-Header': 'my-custom-value', ...options?.headers, }, }); return response.json(); } // ... other methods like put, delete, etc.};Tổ chức các function API request riêng lẻ của bạn trong shared/api/endpoints, nhóm chúng theo API endpoint.
import { client } from '../client';
export interface LoginCredentials { email: string; password: string;}
export function login(credentials: LoginCredentials) { return client.post('/login', credentials);}Sử dụng file index.ts trong shared/api để export các function request của bạn.
export { client } from './client'; // Nếu bạn muốn export clientexport { login } from './endpoints/login';export type { LoginCredentials } from './endpoints/login';Slice-Specific API Requests
Phần tiêu đề “Slice-Specific API Requests”Nếu một API request chỉ được sử dụng bởi một slice cụ thể (như một page hoặc feature đơn lẻ) và sẽ không được tái sử dụng, hãy đặt nó trong segment api của slice đó. Điều này giúp logic slice-specific được chứa đóng một cách gọn gàng.
Thư mụcpages/
Thư mụclogin/
- index.ts
Thư mụcapi/
- login.ts
Thư mụcui/
- LoginPage.tsx
import { client } from 'shared/api';
interface LoginCredentials { email: string; password: string;}
export function login(credentials: LoginCredentials) { return client.post('/login', credentials);}Bạn không cần export function login() trong public API của page, vì không có khả năng nơi nào khác trong app sẽ cần request này.
Sử dụng Client Generators
Phần tiêu đề “Sử dụng Client Generators”Nếu backend của bạn có OpenAPI specification, các công cụ như orval hoặc openapi-typescript có thể generate API types và request functions cho bạn. Đặt code được generate trong, ví dụ, shared/api/openapi. Đảm bảo bao gồm README.md để document những types đó là gì và cách generate chúng.
Tích hợp với Server State Libraries
Phần tiêu đề “Tích hợp với Server State Libraries”Khi sử dụng server state libraries như TanStack Query (React Query) hoặc Pinia Colada, bạn có thể cần chia sẻ types hoặc cache keys giữa các slices. Sử dụng layer shared cho những thứ như:
- API data types
- Cache keys
- Common query/mutation options
Để biết thêm chi tiết về cách làm việc với server state libraries, hãy tham khảo bài viết React Query