Files
gh-hubexab-eaf-pluginclaude…/commands/generate-api-client.md
2025-11-29 18:47:11 +08:00

11 KiB

Generate API Client Command

Generate the TypeScript OpenAPI client library from the NestJS backend API specifications, ensuring type-safe communication between frontend and backend applications.

Usage

/generate-api-client [--watch] [--validate]

Parameters

  • --watch (optional): Watch mode - regenerate client on backend API changes
  • --validate (optional): Validate OpenAPI spec before generation

What This Command Does

This command automates the process of generating a type-safe API client for the frontend to consume the backend API. It:

  1. Extracts OpenAPI specification from the NestJS backend
  2. Validates the specification for correctness
  3. Generates TypeScript client code with full type definitions
  4. Updates the @bdqt/api-client shared library
  5. Ensures type safety across the monorepo

Workflow

When you execute this command, Claude will:

  1. Backend API Specification Extraction

    • Start the NestJS backend in development mode
    • Access the Swagger/OpenAPI endpoint (typically /api-docs)
    • Download the OpenAPI specification JSON
    • Validate the specification structure
  2. Specification Validation (if --validate is used)

    • Check OpenAPI spec version (3.0 or 3.1)
    • Validate all endpoint definitions
    • Ensure all DTOs have proper typing
    • Verify authentication schemes are defined
    • Check for breaking changes from previous version
  3. Client Generation

    • Use OpenAPI Generator or similar tool
    • Generate TypeScript client code with:
      • API service classes
      • Request/response type definitions
      • Model interfaces
      • Authentication helpers
      • HTTP client configuration
  4. Library Update

    • Update libs/api-client/src/ with generated code
    • Run TypeScript compilation
    • Generate TypeScript declarations
    • Update package exports
  5. Verification

    • Compile the generated client
    • Run type checking
    • Verify all dependencies are satisfied
    • Run basic smoke tests

Examples

Basic Generation

/generate-api-client

Generates the API client from the current backend specification.

Generate with Validation

/generate-api-client --validate

Validates the OpenAPI spec before generating the client.

Watch Mode for Development

/generate-api-client --watch

Continuously regenerates the client when backend API changes are detected.

Generated Client Structure

The command generates code in the libs/api-client/ workspace:

libs/api-client/
├── src/
│   ├── api/
│   │   ├── users.api.ts           # Users API endpoints
│   │   ├── auth.api.ts            # Authentication endpoints
│   │   └── index.ts               # API exports
│   ├── models/
│   │   ├── user.model.ts          # User model interface
│   │   ├── auth.model.ts          # Auth-related models
│   │   └── index.ts               # Model exports
│   ├── client.ts                  # HTTP client configuration
│   ├── configuration.ts           # API configuration
│   └── index.ts                   # Main exports
├── package.json
└── tsconfig.json

Client Usage Example

After generation, the frontend can use the type-safe client:

// Frontend service example
import { UsersApi, CreateUserDto, User } from '@bdqt/api-client';

@Injectable()
export class UserService {
  private usersApi: UsersApi;

  constructor(private http: HttpClient) {
    this.usersApi = new UsersApi(http);
  }

  async createUser(data: CreateUserDto): Promise<User> {
    // Full type safety - TypeScript knows all properties
    return this.usersApi.createUser(data).toPromise();
  }
}

Backend Decorators for OpenAPI

Ensure your NestJS controllers use proper decorators:

@Controller('users')
@ApiTags('users')
export class UsersController {
  @Post()
  @ApiOperation({ summary: 'Create a new user' })
  @ApiResponse({ status: 201, description: 'User created', type: User })
  @ApiResponse({ status: 400, description: 'Invalid input' })
  async create(@Body() createUserDto: CreateUserDto): Promise<User> {
    return this.usersService.create(createUserDto);
  }
}

Configuration

Backend OpenAPI Setup

Ensure your NestJS backend has Swagger configured (typically in main.ts):

// apps/backend/src/main.ts
const config = new DocumentBuilder()
  .setTitle('ExFabrica AF API')
  .setDescription('ExFabrica Agentic Factory API')
  .setVersion('1.0')
  .addBearerAuth()
  .build();

const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api-docs', app, document);

Client Generator Configuration

Located in libs/api-client/openapitools.json:

{
  "generator-cli": {
    "version": "6.2.0",
    "generators": {
      "typescript-angular": {
        "inputSpec": "../../apps/backend/openapi.json",
        "output": "./src",
        "generatorName": "typescript-axios",
        "additionalProperties": {
          "npmName": "@bdqt/api-client",
          "supportsES6": true,
          "withInterfaces": true,
          "useSingleRequestParameter": true
        }
      }
    }
  }
}

Output Examples

Success Output

🔧 Generating API Client
========================

✓ Backend API started on http://localhost:3000
✓ OpenAPI specification downloaded
✓ Specification validated (OpenAPI 3.0.3)
✓ Found 24 endpoints across 5 controllers
✓ Client code generated successfully
✓ TypeScript compilation successful
✓ Generated 24 API methods, 18 models

Summary:
--------
Endpoints: 24
Models: 18
Generated Files: 42
Size: 187 KB
Duration: 8.3s

The API client has been updated successfully! ✓

Updated workspace: @bdqt/api-client

Validation Warnings

⚠️  Validation Warnings
-----------------------

1. Missing response type for DELETE /api/users/:id
   Location: UsersController.remove()
   Recommendation: Add @ApiResponse decorator

2. DTO missing property descriptions
   Location: CreateUserDto
   Affected: email, password, firstName, lastName
   Recommendation: Add @ApiProperty({ description: '...' })

3. Deprecated endpoint still in use
   Location: GET /api/auth/legacy-login
   Recommendation: Remove or mark with @Deprecated

Client generated successfully, but consider fixing these warnings.

Watch Mode

When running with --watch, the command monitors:

  • Changes to *.controller.ts files in backend
  • Changes to *.dto.ts files in backend
  • Changes to OpenAPI decorators
  • Manual OpenAPI spec updates

On detecting changes:

  1. Debounces for 2 seconds (batch multiple changes)
  2. Re-extracts OpenAPI specification
  3. Compares with previous version
  4. Regenerates only if changes detected
  5. Notifies you of the update

Troubleshooting

Backend Not Starting

Error: Cannot start backend server

Solution: Ensure backend dependencies are installed and database is running

yarn install
docker compose up -d

OpenAPI Spec Invalid

Error: Invalid OpenAPI specification

Solution: Check backend controller decorators and DTOs

  • Ensure all endpoints have proper @ApiOperation
  • Verify DTOs have @ApiProperty decorators
  • Check for circular references

Type Generation Errors

Error: Failed to generate TypeScript types

Solution: Update OpenAPI generator version

cd libs/api-client
yarn add -D @openapitools/openapi-generator-cli@latest

Circular Dependency Detected

Error: Circular reference in User -> Profile -> User

Solution: Restructure models or use lazy imports

// Use string reference instead of direct import
@ApiProperty({ type: () => 'Profile' })
profile?: Profile;

Missing Authentication Types

Error: Cannot find 'Authorization' header type

Solution: Add authentication configuration to OpenAPI setup

.addBearerAuth({ type: 'http', scheme: 'bearer', bearerFormat: 'JWT' })

Breaking Changes Detection

The command detects breaking changes between versions:

Breaking Changes

  • Removed endpoints
  • Changed request/response types
  • Removed model properties
  • Changed authentication requirements

Non-Breaking Changes

  • New endpoints
  • New optional properties
  • Added documentation
  • New response codes

If breaking changes are detected, you'll receive a warning and recommendations for migration.

Best Practices

  1. Regenerate after backend API changes

    # After modifying backend controllers/DTOs
    /generate-api-client --validate
    
  2. Use watch mode during active development

    /generate-api-client --watch
    
  3. Commit generated client with backend changes

    • Keeps frontend and backend in sync
    • Enables type checking across the monorepo
  4. Document your API properly

    @ApiOperation({
      summary: 'Create user',
      description: 'Creates a new user account with the provided details'
    })
    @ApiResponse({
      status: 201,
      description: 'User successfully created',
      type: User
    })
    
  5. Version your API

    • Use API versioning in routes (/api/v1/users)
    • Generate separate clients for different versions if needed

Integration with Development Workflow

Before Deployment

/generate-api-client --validate
/test-all
/deploy staging

After Backend Changes

# Make backend changes
/generate-api-client
# Update frontend to use new types
/test-all frontend

In CI/CD Pipeline

- task: Script@1
  displayName: 'Generate API Client'
  inputs:
    script: |
      /generate-api-client --validate

- task: Script@1
  displayName: 'Verify No Changes'
  inputs:
    script: |
      git diff --exit-code libs/api-client/
      # Fails if generated code differs (means it wasn't regenerated)

Advanced Usage

Custom Generator Configuration

Modify libs/api-client/openapitools.json for custom generation:

{
  "additionalProperties": {
    "npmName": "@bdqt/api-client",
    "supportsES6": true,
    "withInterfaces": true,
    "useSingleRequestParameter": true,
    "modelPropertyNaming": "camelCase",
    "enumPropertyNaming": "UPPERCASE"
  }
}

Multiple API Versions

Generate clients for different API versions:

/generate-api-client v1
/generate-api-client v2

Each version gets its own namespace:

  • @bdqt/api-client/v1
  • @bdqt/api-client/v2
  • /test-all - Test generated client integration
  • /deploy - Deploy after client generation
  • /analyze-code - Verify generated code quality

Benefits

Type Safety: Full TypeScript typing across frontend-backend boundary ✓ Auto-completion: IDE support for all API methods and models ✓ Error Prevention: Catch API mismatches at compile time ✓ Documentation: Generated client includes JSDoc from backend ✓ Consistency: Single source of truth for API contracts ✓ Productivity: No manual API client maintenance


Note: Always regenerate the client after making changes to backend API endpoints, DTOs, or authentication schemes to maintain type safety across the monorepo.