ai-voicebot/docs/AUTOMATED_API_CLIENT.md

239 lines
8.1 KiB
Markdown

# Automated API Client Generation System
This document explains the automated TypeScript API client generation and update system for the AI Voicebot project.
## Overview
The system automatically:
1. **Generates OpenAPI schema** from FastAPI server
2. **Creates TypeScript types** from the schema
3. **Updates API client** with missing endpoint implementations using dynamic paths
4. **Updates evolution checker** with current endpoint lists
5. **Validates TypeScript** compilation
6. **Runs evolution checks** to ensure completeness
All generated API calls use the `PUBLIC_URL` environment variable to dynamically construct paths, making the system deployable to any base path without hardcoded `/ai-voicebot` prefixes.
## Files in the System
### Generated Files (Auto-updated)
- `client/openapi-schema.json` - OpenAPI schema from server
- `client/src/api-types.ts` - TypeScript type definitions
- `client/src/api-client.ts` - API client (auto-sections updated)
- `client/src/api-evolution-checker.ts` - Evolution checker (lists updated)
### Manual Files
- `generate-ts-types.sh` - Main orchestration script
- `client/update-api-client.js` - API client updater utility
- `client/src/api-usage-examples.ts` - Usage examples and patterns
## Configuration
### Environment Variables
The system uses environment variables for dynamic path configuration:
- **`PUBLIC_URL`** - Base path for the application (e.g., `/ai-voicebot`, `/my-app`, etc.)
- Used in: API paths, schema loading, asset paths
- Default: `""` (empty string for root deployment)
- Set in: Docker environment, build process, or runtime
### Dynamic Path Handling
All API endpoints use dynamic path construction:
```typescript
// Instead of hardcoded paths:
// "/ai-voicebot/api/health"
// The system uses:
this.getApiPath("/ai-voicebot/api/health")
// Which becomes: `${PUBLIC_URL}/api/health`
```
This allows deployment to different base paths without code changes.
## Usage
### Full Generation (Recommended)
```bash
./generate-ts-types.sh
```
This runs the complete pipeline and is the primary way to use the system.
### Individual Steps
```bash
# Inside client container
npm run generate-schema # Generate OpenAPI schema
npm run generate-types # Generate TypeScript types
npm run update-api-client # Update API client
npm run check-api-evolution # Check for missing endpoints
```
## How Auto-Updates Work
### API Client Updates
The `update-api-client.js` script:
1. **Parses OpenAPI schema** to find all available endpoints
2. **Scans existing API client** to detect implemented methods
3. **Identifies missing endpoints** by comparing the two
4. **Generates method implementations** for missing endpoints
5. **Updates the client class** by inserting new methods in designated section
6. **Updates endpoint lists** used by evolution checking
#### Auto-Generated Section
```typescript
export class ApiClient {
// ... manual methods ...
/**
* Construct API path using PUBLIC_URL environment variable
* Replaces hardcoded /ai-voicebot prefix with dynamic base from environment
*/
private getApiPath(schemaPath: string): string {
return schemaPath.replace('/ai-voicebot', base);
}
// Auto-generated endpoints will be added here by update-api-client.js
// DO NOT MANUALLY EDIT BELOW THIS LINE
// New endpoints automatically appear here using this.getApiPath()
}
```
#### Method Generation
- **Method names** derived from `operationId` or path/method combination
- **Parameters** inferred from path parameters and request body
- **Return types** use generic `Promise<any>` (can be enhanced)
- **Path handling** supports both static and parameterized paths using `PUBLIC_URL`
- **Dynamic paths** automatically replace hardcoded prefixes with environment-based values
### Evolution Checker Updates
The evolution checker tracks:
- **Known schema endpoints** - updated from current OpenAPI schema
- **Implemented endpoints** - updated from actual API client code
- **Missing endpoints** - calculated difference for warnings
## Customization
### Adding Manual Endpoints
For endpoints not in OpenAPI schema (e.g., external services), add them manually before the auto-generated section:
```typescript
// Manual endpoints (these won't be auto-generated)
async getCustomData(): Promise<CustomResponse> {
return this.request<CustomResponse>("/custom/endpoint", { method: "GET" });
}
// Auto-generated endpoints will be added here by update-api-client.js
// DO NOT MANUALLY EDIT BELOW THIS LINE
```
### Improving Generated Methods
To enhance auto-generated methods:
1. **Better Type Inference**: Modify `generateMethodSignature()` in `update-api-client.js` to use specific types from schema
2. **Parameter Validation**: Add validation logic in method generation
3. **Error Handling**: Customize error handling patterns
4. **Documentation**: Add JSDoc generation from OpenAPI descriptions
### Schema Evolution Detection
The system detects:
- **New endpoints** added to OpenAPI schema
- **Changed endpoints** (parameter or response changes)
- **Deprecated endpoints** (with proper OpenAPI marking)
## Development Workflow
1. **Develop API endpoints** in FastAPI server with proper typing
2. **Run generation script** to update client: `./generate-ts-types.sh`
3. **Use generated types** in React components
4. **Manual customization** for complex endpoints if needed
5. **Commit all changes** including generated and updated files
## Best Practices
### Server Development
- Use **Pydantic models** for all request/response types
- Add **proper OpenAPI metadata** (summary, description, tags)
- Use **consistent naming** for operation IDs
- **Version your API** to handle breaking changes
### Client Development
- **Import from api-client.ts** rather than making raw fetch calls
- **Use generated types** for type safety
- **Avoid editing auto-generated sections** - they will be overwritten
- **Add custom endpoints manually** when needed
### Type Safety
```typescript
// Good: Using generated types and client
import { apiClient, type LobbyModel, type LobbyCreateRequest } from './api-client';
const createLobby = async (data: LobbyCreateRequest): Promise<LobbyModel> => {
const response = await apiClient.createLobby(sessionId, data);
return response.data; // Fully typed
};
// Avoid: Direct fetch calls
const createLobbyRaw = async () => {
const response = await fetch('/api/lobby', { /* ... */ });
return response.json(); // No type safety
};
```
## Troubleshooting
### Common Issues
**"Could not find insertion marker"**
- The API client file was manually edited and the auto-generation markers were removed
- Restore the markers or regenerate the client file from template
**"Missing endpoints detected"**
- New endpoints were added to the server but the generation script wasn't run
- Run `./generate-ts-types.sh` to update the client
**"Type errors after generation"**
- Schema changes may have affected existing manual code
- Check the TypeScript compiler output and update affected code
**"Duplicate method names"**
- Manual methods conflict with auto-generated ones
- Rename manual methods or adjust the operation ID generation logic
### Debug Mode
Add debug logging by modifying `update-api-client.js`:
```javascript
// Add after parsing
console.log('Schema endpoints:', this.endpoints.map(e => `${e.method}:${e.path}`));
console.log('Implemented endpoints:', Array.from(this.implementedEndpoints));
```
## Future Enhancements
- **Stronger type inference** from OpenAPI schema components
- **Request/response validation** using schema definitions
- **Mock data generation** for testing
- **API versioning support** with backward compatibility
- **Performance optimization** with request caching
- **OpenAPI spec validation** before generation
## Integration with Build Process
The system integrates with:
- **Docker Compose** for cross-container coordination
- **npm scripts** for frontend build pipeline
- **TypeScript compilation** for type checking
- **CI/CD workflows** for automated updates
This ensures that API changes are automatically reflected in the frontend without manual intervention, reducing development friction and preventing API/client drift.