> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/charlietyn/openapi-generator/llms.txt
> Use this file to discover all available pages before exploring further.

# Package Overview

> Learn how Laravel OpenAPI Generator works under the hood

## How It Works

Laravel OpenAPI Generator automatically scans your Laravel routes and generates comprehensive API documentation in multiple formats. The package follows a clear architecture that transforms your application's routes into structured documentation.

<CardGroup cols={3}>
  <Card title="Route Scanning" icon="radar">
    Automatically discovers API routes by inspecting Laravel's routing system
  </Card>

  <Card title="Metadata Extraction" icon="magnifying-glass">
    Analyzes controllers, FormRequests, and models to build complete specs
  </Card>

  <Card title="Multi-Format Output" icon="file-export">
    Generates OpenAPI, Postman, and Insomnia documentation from a single source
  </Card>
</CardGroup>

## Architecture

The package uses a layered architecture to generate documentation:

```mermaid theme={null}
graph TD
    A[Laravel Routes] --> B[OpenApiServices]
    B --> C[Route Inspector]
    C --> D[Documentation Resolver]
    D --> E[Metadata Extractor]
    D --> F[Template Processor]
    E --> G[OpenAPI Spec]
    F --> G
    G --> H[Postman Generator]
    G --> I[Insomnia Generator]
    G --> J[OpenAPI JSON]
```

### Core Components

<Accordion title="OpenApiServices" icon="gear">
  The main orchestrator that coordinates the entire generation process.

  **Key Responsibilities:**

  * Route inspection and filtering
  * API type filtering
  * Cache management
  * Format conversion

  ```php theme={null}
  // Example: Generate with filters
  $generator = app(OpenApiGenerator::class);

  $spec = $generator->generate(
      useCache: true,
      apiTypes: ['admin', 'mobile'],
      environment: 'production',
      format: 'openapi'
  );
  ```
</Accordion>

<Accordion title="Route Inspector" icon="magnifying-glass">
  Scans Laravel's route collection and identifies API routes based on configured prefixes.

  **Route Filtering Logic:**

  ```php theme={null}
  protected function inspectRoutes(): void
  {
      $routes = Route::getRoutes();
      $excludePatterns = config('openapi.exclude_routes', []);

      foreach ($routes as $route) {
          $uri = $route->uri();

          // Skip excluded routes
          if ($this->shouldExcludeRoute($uri, $excludePatterns)) {
              continue;
          }

          // Only process API routes
          if (!$this->isApiRoute($uri)) {
              continue;
          }

          // Apply API type filter
          if ($this->apiTypeFilter && !$this->matchesApiTypeFilter($uri)) {
              continue;
          }

          $this->processRoute($route);
      }
  }
  ```

  **What Gets Scanned:**

  * All routes starting with configured API prefixes (`admin`, `site`, `mobile`)
  * Routes not matching exclude patterns
  * Routes that pass API type filters
</Accordion>

<Accordion title="Documentation Resolver" icon="book">
  Resolves documentation for each endpoint using multiple sources:

  **Priority System:**

  1. **JSON Templates** - Pre-defined resource documentation
  2. **FormRequest Rules** - Validation rules from Form Request classes
  3. **Model Attributes** - Database schema from Eloquent models
  4. **Generic Fallback** - Default schemas when no metadata is found

  ```php theme={null}
  $documentation = $this->docResolver->resolveForOperation(
      entity: 'users',
      action: 'create',
      controller: 'UserController',
      route: $route
  );
  ```
</Accordion>

<Accordion title="Metadata Extractor" icon="database">
  Extracts field definitions from FormRequests and Models.

  **From FormRequest:**

  ```php theme={null}
  // App/Http/Requests/StoreUserRequest.php
  public function rules(): array
  {
      return [
          'name' => 'required|string|max:255',
          'email' => 'required|email|unique:users',
          'role_id' => 'required|exists:roles,id',
      ];
  }
  ```

  **Generates:**

  ```json theme={null}
  {
    "type": "object",
    "required": ["name", "email", "role_id"],
    "properties": {
      "name": {"type": "string", "maxLength": 255},
      "email": {"type": "string", "format": "email"},
      "role_id": {"type": "integer"}
    }
  }
  ```
</Accordion>

## Route Processing Flow

### 1. Route Discovery

```php theme={null}
// config/openapi.php - API Types define route prefixes
'api_types' => [
    'admin' => [
        'prefix' => 'admin',
        'enabled' => true,
    ],
    'mobile' => [
        'prefix' => 'mobile',
        'enabled' => true,
    ],
],
```

The package scans routes starting with these prefixes:

* `admin/*` → Included in admin API type
* `mobile/*` → Included in mobile API type
* `site/*` → Included in site API type

### 2. URI Structure Parsing

<Tabs>
  <Tab title="Modular Routes">
    Routes following the modular pattern: `/{prefix}/{module}/{entity}/{action}`

    ```
    POST /admin/security/users
    └─ Parsed as:
       ├─ Prefix: admin
       ├─ Module: security
       ├─ Entity: users
       └─ Action: create
    ```

    **Detection Logic:**

    ```php theme={null}
    protected function parseUriStructure(string $uri): array
    {
        $parts = explode('/', trim($uri, '/'));
        
        if ($this->isNwidartModule($parts[1])) {
            return [
                'prefix' => $parts[0],
                'module' => $parts[1],
                'entity' => $parts[2],
            ];
        }
    }
    ```
  </Tab>

  <Tab title="Global Entity Routes">
    Routes for global models in `App\Models`:

    ```
    GET /admin/roles
    └─ Parsed as:
       ├─ Prefix: admin
       ├─ Module: general
       ├─ Entity: roles
       └─ Action: list
    ```

    **Detection Logic:**

    ```php theme={null}
    if ($this->isGlobalEntityModel($secondSegment)) {
        return [
            'prefix' => $prefix,
            'module' => 'general',
            'entity' => $secondSegment,
        ];
    }
    ```
  </Tab>

  <Tab title="Custom Actions">
    Routes with custom endpoint actions:

    ```
    POST /admin/api-apps/{id}/rotate
    └─ Parsed as:
       ├─ Prefix: admin
       ├─ Module: general
       ├─ Entity: api-apps
       └─ Action: rotate (extracted from URI)
    ```

    **Action Extraction:**

    ```php theme={null}
    protected function extractActionFromUri(string $uri): string
    {
        $parts = explode('/', trim($uri, '/'));
        $nonParams = array_filter($parts, 
            fn($p) => !Str::startsWith($p, '{'));
        
        // Last non-parameter segment is the action
        return end($nonParams);
    }
    ```
  </Tab>
</Tabs>

### 3. Operation Building

For each route, the generator creates an OpenAPI operation:

```php theme={null}
protected function buildOperation($route, string $method): array
{
    $structure = $this->parseUriStructure($route->uri());
    $action = $this->extractAction($route->getAction(), $method);
    
    // Resolve documentation
    $documentation = $this->docResolver->resolveForOperation(
        $structure['entity'],
        $action,
        $controllerClass,
        $route
    );
    
    return [
        'operationId' => "{$structure['module']}.{$structure['entity']}.{$action}",
        'summary' => "[{$structure['prefix']}] {$summary}",
        'description' => $documentation['description'] ?? '',
        'tags' => [$structure['module']],
        'parameters' => $this->extractParameters($route),
        'requestBody' => $this->buildRequestBody($documentation),
        'responses' => $this->buildResponses($method, $action),
        'security' => $this->extractSecurity($route),
    ];
}
```

## Caching Strategy

<Info>
  Generated specifications are cached to improve performance on subsequent requests.
</Info>

```php theme={null}
// config/openapi.php
'cache' => [
    'enabled' => env('OPENAPI_CACHE_ENABLED', true),
    'ttl' => env('OPENAPI_CACHE_TTL', 3600), // 1 hour
    'key_prefix' => 'openapi_spec_',
],
```

**Cache Key Structure:**

```php theme={null}
// Format: openapi_spec_{apiTypes}_{environment}_{format}
'openapi_spec_admin_mobile_production_openapi'
'openapi_spec_all_artisan_postman'
```

**Clear Cache:**

```bash theme={null}
php artisan openapi:clear-cache
```

## Output Formats

### OpenAPI 3.0.3

The canonical specification format. Used as the base for all other formats.

```json theme={null}
{
  "openapi": "3.0.3",
  "info": {
    "title": "My API (Admin, Mobile)",
    "version": "1.0.0"
  },
  "paths": {
    "/admin/users": {
      "get": {
        "operationId": "general.users.list",
        "tags": ["Users"]
      }
    }
  }
}
```

### Postman Collection

Converts OpenAPI to Postman Collection v2.1 format with:

* Test scripts for CRUD operations
* Environment variable tracking
* Organized folder structure

### Insomnia Workspace

Converts to Insomnia v4 workspace format with:

* Multiple environment configurations
* Request chaining support
* Folder hierarchy

<Note>
  All three formats are generated from the same OpenAPI specification, ensuring consistency across tools.
</Note>

## Next Steps

<CardGroup cols={2}>
  <Card title="API Types" icon="layer-group" href="/concepts/api-types">
    Learn how to organize routes into different API types
  </Card>

  <Card title="Environments" icon="globe" href="/concepts/environments">
    Configure multiple deployment environments
  </Card>
</CardGroup>
