v2

OpenAPI Specification Generation

This document explains how OpenAPI/Swagger documentation is generated and configured in the Loreax platform.

Overview

The Loreax API uses darkaonline/l5-swagger to automatically generate OpenAPI 3.0 specification from controller annotations. The generated specification is environment-aware, ensuring that API paths correctly reflect the deployment environment.

Generation Workflow

1. Base Generation

The base OpenAPI specification is generated from PHP annotations in controller classes:

php artisan l5-swagger:generate

This command:

  • Scans all controllers with OpenApi\Attributes annotations
  • Extracts endpoint definitions, request/response schemas, and authentication requirements
  • Generates storage/api-docs/api-docs.json

2. Environment-Aware Post-Processing

After base generation, the specification is post-processed to inject environment-specific server configuration:

php artisan loreax:postprocess-openapi

This command:

  • Reads APP_URL and LOREAX_API_PREFIX from configuration
  • Constructs the correct server URL based on the environment
  • Updates the servers array in the generated JSON file

Examples:

  • Local/Test: http://localhost:8000/api/v1 (when LOREAX_API_PREFIX=api/v1)
  • Production: https://api.loreax.bervant.co.ke/v1 (when LOREAX_API_PREFIX=v1)

3. Deployment Integration

Both commands are automatically executed during deployment:

# From deployment/ec2/scripts/deploy.sh
php artisan l5-swagger:generate
php artisan loreax:postprocess-openapi

Environment Configuration

Local/Test Environments

Set LOREAX_API_PREFIX=api/v1 to serve API endpoints with the /api/v1 prefix. This allows disambiguation when all surfaces (API, admin, dev) run on a single host.

APP_URL=http://localhost:8000
LOREAX_API_PREFIX=api/v1

Result: API endpoints accessible at http://localhost:8000/api/v1/*

Production/Hyena Environments

Set LOREAX_API_PREFIX=v1 when the API has its own subdomain. The /api prefix is dropped since subdomain routing already isolates the API surface.

APP_URL=https://api.loreax.bervant.co.ke
LOREAX_API_PREFIX=v1

Result: API endpoints accessible at https://api.loreax.bervant.co.ke/v1/*

Git Workflow

The generated OpenAPI specification is not committed to version control. It is generated fresh during each deployment to ensure it reflects the current codebase and environment.

.gitignore includes:

/storage/api-docs/

Controller Annotations

Controllers define endpoints using OpenApi\Attributes PHP attributes:

use OpenApi\Attributes as OA;

#[OA\Post(
    path: '/v1/auth/login',
    summary: 'Authenticate and receive access token',
    tags: ['Identity'],
    requestBody: new OA\RequestBody(/* ... */),
    responses: [
        new OA\Response(response: 200, description: 'Authenticated'),
        new OA\Response(response: 401, description: 'Invalid credentials'),
    ],
)]
public function __invoke(LoginRequest $request): ApiResponse
{
    // Implementation
}

Important: The path in annotations includes the /v1 version segment but excludes the environment-specific prefix (/api). The post-processor adds the correct server base URL.

OpenAPI Specification Location

Base definition: app/Core/OpenApi/OpenApiSpec.php

  • Contains global API metadata (title, version, description)
  • Defines authentication schemes
  • Defines reusable schemas

Generated output: storage/api-docs/api-docs.json

  • Complete OpenAPI 3.0 specification
  • Generated from controller annotations + base definition
  • Post-processed with environment-aware server URLs
  • Served at /docs/api via Swagger UI

Viewing Documentation

Development:

http://localhost:8000/docs/api

Production:

https://dev.loreax.bervant.co.ke/docs/api

Troubleshooting

Swagger UI shows wrong API paths

Run the post-processor manually:

php artisan loreax:postprocess-openapi

Check the servers array in storage/api-docs/api-docs.json matches your environment.

Missing endpoints in documentation

Controllers must:

  1. Use OpenApi\Attributes annotations
  2. Be registered in route discovery (via RouteRegistrar in routes/api.php)
  3. Have the #[OA\Post], #[OA\Get], etc. attribute on the controller method

Regenerate after adding annotations:

php artisan l5-swagger:generate
php artisan loreax:postprocess-openapi

Validation errors on generation

Check for:

  • Missing required properties in OA\RequestBody or OA\Response definitions
  • Invalid JSON schema syntax in request/response bodies
  • Undefined schema references (ref: '#/components/schemas/...')

Run with verbose output:

php artisan l5-swagger:generate --verbose

References