API Client Generator
Category: Code Generation October 15, 2025
Generate type-safe API client code from OpenAPI/Swagger specifications with error handling.
APICode GenerationTypeScriptOpenAPIClient SDK
# API Client Generator
Generate a complete, type-safe API client library from OpenAPI/Swagger specifications with proper error handling, authentication, and retries.
## Generated Client Features
### 1. Type Safety
- Generate TypeScript interfaces for all models
- Type-safe request/response handling
- Enum types for fixed values
- Generic types for paginated responses
- Discriminated unions for polymorphic types
### 2. HTTP Client
- Configurable base URL
- Request/response interceptors
- Automatic retries with exponential backoff
- Timeout handling
- Cancel token support
### 3. Authentication
- Bearer token support
- API key authentication
- OAuth 2.0 flow
- Token refresh logic
- Credential storage
### 4. Error Handling
- Typed error responses
- HTTP status code handling
- Network error handling
- Validation errors
- Custom error classes
## Example Output
### Generated Types
```typescript
// Generated from OpenAPI schema
export interface User {
id: number;
email: string;
name: string;
role: UserRole;
createdAt: string;
updatedAt: string;
}
export enum UserRole {
Admin = 'admin',
User = 'user',
Guest = 'guest'
}
export interface PaginatedResponse<T> {
data: T[];
page: number;
pageSize: number;
total: number;
}
export interface ApiError {
code: string;
message: string;
details?: Record<string, string[]>;
}
Generated Client
export class ApiClient {
private baseURL: string;
private token?: string;
constructor(config: ApiConfig) {
this.baseURL = config.baseURL;
this.token = config.token;
}
// Users endpoint
async getUsers(params?: {
page?: number;
pageSize?: number;
role?: UserRole;
}): Promise<PaginatedResponse<User>> {
return this.request<PaginatedResponse<User>>('GET', '/users', { params });
}
async getUser(id: number): Promise<User> {
return this.request<User>('GET', `/users/${id}`);
}
async createUser(data: CreateUserRequest): Promise<User> {
return this.request<User>('POST', '/users', { data });
}
async updateUser(id: number, data: UpdateUserRequest): Promise<User> {
return this.request<User>('PUT', `/users/${id}`, { data });
}
async deleteUser(id: number): Promise<void> {
return this.request<void>('DELETE', `/users/${id}`);
}
// Core request method
private async request<T>(
method: string,
path: string,
options?: RequestOptions
): Promise<T> {
const url = `${this.baseURL}${path}`;
const headers = {
'Content-Type': 'application/json',
...(this.token && { Authorization: `Bearer ${this.token}` }),
...options?.headers,
};
try {
const response = await fetch(url, {
method,
headers,
body: options?.data ? JSON.stringify(options.data) : undefined,
signal: options?.signal,
});
if (!response.ok) {
throw await this.handleErrorResponse(response);
}
if (response.status === 204) {
return undefined as T;
}
return await response.json();
} catch (error) {
if (error instanceof ApiError) throw error;
throw new NetworkError('Network request failed', error);
}
}
private async handleErrorResponse(response: Response): Promise<ApiError> {
const body = await response.json().catch(() => ({}));
return new ApiError(
body.code || `HTTP_${response.status}`,
body.message || response.statusText,
body.details
);
}
}
Usage Example
// Initialize client
const api = new ApiClient({
baseURL: 'https://api.example.com/v1',
token: 'your-auth-token',
});
// Use type-safe methods
try {
const users = await api.getUsers({ page: 1, pageSize: 20, role: UserRole.Admin });
console.log(`Found ${users.total} users`);
const user = await api.getUser(users.data[0].id);
console.log(user.name);
const newUser = await api.createUser({
email: 'new@example.com',
name: 'New User',
role: UserRole.User,
});
} catch (error) {
if (error instanceof ApiError) {
console.error(`API Error: ${error.code} - ${error.message}`);
if (error.details) {
console.error('Validation errors:', error.details);
}
} else if (error instanceof NetworkError) {
console.error('Network error:', error.message);
}
}
Generation Checklist
- All endpoints covered
- Request/response types generated
- Authentication implemented
- Error handling complete
- Retries with backoff
- Request cancellation supported
- Documentation generated
- Example code provided
- Tests generated
- Published to npm/registry