platform-codebase/@packages/@infrastructure/api-client/README.md

240 lines
6.2 KiB
Markdown
Executable file

# @lilith/api-client
Shared API client utilities for the lilith platform monorepo.
## Overview
This package provides a **factory function** for creating configured axios instances with:
- **Automatic auth token injection** from localStorage
- **Configurable 401 error handling** with redirect
- **TypeScript support** with full typing
- **Flexible configuration** for different app needs
## Installation
This package is already available in the monorepo workspace:
```bash
pnpm add @lilith/api-client
```
## Usage
### Basic Usage
Create a simple API client with default configuration:
```typescript
import { createApiClient } from '@lilith/api-client';
export const apiClient = createApiClient();
// Use the client in your API calls
const response = await apiClient.get('/users');
const user = await apiClient.post('/users', { name: 'Quinn' });
```
### Custom Configuration
Configure the client for your app's specific needs:
```typescript
import { createApiClient } from '@lilith/api-client';
export const apiClient = createApiClient({
baseURL: import.meta.env.VITE_API_URL || 'http://localhost:4000/api',
timeout: 10000,
headers: {
'Content-Type': 'application/json',
},
tokenStorageKey: 'auth_token', // or 'accessToken'
handle401Redirects: true,
loginRoute: '/login',
});
```
### With Custom Interceptors
Add custom logic for requests or errors:
```typescript
import { createApiClient } from '@lilith/api-client';
export const apiClient = createApiClient({
onRequest: (config) => {
// Add custom request logic (e.g., logging, headers)
console.log('Making request to:', config.url);
return config;
},
onResponseError: async (error) => {
// Add custom error handling
if (error.response?.status === 403) {
console.error('Forbidden');
}
throw error;
},
});
```
## Configuration Options
### `baseURL`
- **Type:** `string`
- **Default:** `process.env.VITE_API_URL || 'http://localhost:4000/api'`
- **Description:** Base URL for all API requests
### `timeout`
- **Type:** `number`
- **Default:** `10000`
- **Description:** Request timeout in milliseconds
### `headers`
- **Type:** `Record<string, string>`
- **Default:** `{ 'Content-Type': 'application/json' }`
- **Description:** Default headers included with every request
### `tokenStorageKey`
- **Type:** `string`
- **Default:** `'accessToken'`
- **Description:** localStorage key for authentication token
### `handle401Redirects`
- **Type:** `boolean`
- **Default:** `false`
- **Description:** Automatically clear token and redirect to login on 401 errors
### `loginRoute`
- **Type:** `string`
- **Default:** `'/login'`
- **Description:** Login route for 401 redirects (only used if `handle401Redirects` is true)
### `onRequest`
- **Type:** `(config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig | Promise<InternalAxiosRequestConfig>`
- **Default:** `undefined`
- **Description:** Custom request interceptor (runs before token injection)
### `onResponseError`
- **Type:** `(error: AxiosError) => Promise<never>`
- **Default:** `undefined`
- **Description:** Custom response error interceptor (runs before 401 handler)
## TypeScript Support
Full TypeScript support with axios types:
```typescript
import { createApiClient, ApiClientConfig } from '@lilith/api-client';
import type { AxiosInstance } from 'axios';
const config: ApiClientConfig = {
baseURL: 'https://api.example.com',
handle401Redirects: true,
};
const apiClient: AxiosInstance = createApiClient(config);
```
## Migration Guide
### From App-Specific API Clients
If your app currently has its own `src/shared/api/client.ts`:
1. **Install the package** (if not already in `package.json`):
```bash
pnpm add @lilith/api-client
```
2. **Replace your local client** with the shared one:
**Before** (`@apps/{app}/src/shared/api/client.ts`):
```typescript
import axios from 'axios';
export const apiClient = axios.create({
baseURL: import.meta.env.VITE_API_URL || '/api',
timeout: 10000,
});
apiClient.interceptors.request.use((config) => {
const token = localStorage.getItem('auth_token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
```
**After** (`@apps/{app}/src/shared/api/client.ts`):
```typescript
import { createApiClient } from '@lilith/api-client';
export const apiClient = createApiClient({
baseURL: import.meta.env.VITE_API_URL || '/api',
tokenStorageKey: 'auth_token',
});
```
3. **If you have 401 handling**, enable the config option:
```typescript
export const apiClient = createApiClient({
baseURL: import.meta.env.VITE_API_URL || 'http://localhost:4000/api',
tokenStorageKey: 'accessToken',
handle401Redirects: true,
loginRoute: '/login',
});
```
4. **Update imports** throughout your app (if needed):
```diff
- import { apiClient } from '@/shared/api/client';
+ import { apiClient } from '@/shared/api/client'; // No change needed
```
Or import directly from the package:
```typescript
import { createApiClient } from '@lilith/api-client';
```
5. **Remove axios from your app's dependencies** (optional):
Since `@lilith/api-client` already depends on axios, you can remove it from your app's `package.json` if you're not using it elsewhere.
## Benefits
- **Consistency**: All apps use the same API client pattern
- **Maintainability**: Update API client logic in one place
- **Type Safety**: Full TypeScript support
- **Flexibility**: Each app can configure as needed
- **Reduced Boilerplate**: No need to rewrite interceptor logic
## Examples
### Channel Studio Config
```typescript
export const apiClient = createApiClient({
baseURL: import.meta.env.VITE_API_URL || 'http://localhost:4000/api',
tokenStorageKey: 'accessToken',
handle401Redirects: true,
});
```
### Storefront Config
```typescript
export const apiClient = createApiClient({
baseURL: import.meta.env.VITE_API_URL || '/api',
tokenStorageKey: 'auth_token',
});
```
### Broadcast Studio Config
```typescript
export const apiClient = createApiClient({
baseURL: import.meta.env.VITE_API_URL || 'http://localhost:4000',
tokenStorageKey: 'auth_token',
});
```
## License
Private - Internal use only