ai-voicebot/docs/AUTOMATED_API_CLIENT.md

8.1 KiB

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:

// 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

./generate-ts-types.sh

This runs the complete pipeline and is the primary way to use the system.

Individual Steps

# 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

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:

// 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

// 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:

// 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.