Skip to main content

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.

Overview

The Laravel OpenAPI Generator does not include custom middleware classes. Instead, it provides configuration options to apply your existing Laravel middleware to the HTTP documentation routes.
HTTP routes are only available when openapi.routes.enabled is set to true in the configuration.

Configuration

Route Middleware

Configure middleware for the documentation routes in config/openapi.php:
'routes' => [
    'enabled' => true,
    'prefix' => 'documentation',
    'middleware' => ['web'], // Apply middleware here
],
Location: config/openapi.php

Common Middleware Patterns

Public Access (Default)

No authentication required - suitable for public APIs:
'routes' => [
    'enabled' => true,
    'prefix' => 'documentation',
    'middleware' => ['web'],
],

Authenticated Access (Sanctum)

Require authentication via Laravel Sanctum:
'routes' => [
    'enabled' => true,
    'prefix' => 'documentation',
    'middleware' => ['auth:sanctum'],
],
Usage: Users must provide a valid token to access documentation:
curl -H "Authorization: Bearer YOUR_TOKEN" \
  http://localhost:8000/documentation/openapi.json

Session Authentication

Require authenticated session (for web-based access):
'routes' => [
    'enabled' => true,
    'prefix' => 'documentation',
    'middleware' => ['web', 'auth'],
],

Admin-Only Access

Restrict access to admin users:
'routes' => [
    'enabled' => true,
    'prefix' => 'documentation',
    'middleware' => ['auth:sanctum', 'admin'], // Assuming you have an 'admin' middleware
],
Example Admin Middleware:
// app/Http/Middleware/EnsureUserIsAdmin.php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class EnsureUserIsAdmin
{
    public function handle(Request $request, Closure $next)
    {
        if (!$request->user() || !$request->user()->is_admin) {
            abort(403, 'Access denied');
        }

        return $next($request);
    }
}
Register in app/Http/Kernel.php:
protected $middlewareAliases = [
    // ...
    'admin' => \App\Http\Middleware\EnsureUserIsAdmin::class,
];

IP Whitelist

Restrict access to specific IP addresses:
'routes' => [
    'enabled' => true,
    'prefix' => 'documentation',
    'middleware' => ['web', 'ip.whitelist'],
],
Example IP Whitelist Middleware:
// app/Http/Middleware/IpWhitelist.php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class IpWhitelist
{
    protected array $whitelist = [
        '127.0.0.1',
        '::1',
        // Add your allowed IPs
    ];

    public function handle(Request $request, Closure $next)
    {
        if (!in_array($request->ip(), $this->whitelist)) {
            abort(403, 'Access denied from your IP address');
        }

        return $next($request);
    }
}

Environment-Based Access

Allow access only in development environments:
'routes' => [
    'enabled' => env('APP_ENV') !== 'production',
    'prefix' => 'documentation',
    'middleware' => ['web'],
],
Or use middleware:
'routes' => [
    'enabled' => true,
    'prefix' => 'documentation',
    'middleware' => ['web', 'dev.only'],
],
Example Development-Only Middleware:
// app/Http/Middleware/DevelopmentOnly.php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class DevelopmentOnly
{
    public function handle(Request $request, Closure $next)
    {
        if (!app()->environment(['local', 'development'])) {
            abort(404);
        }

        return $next($request);
    }
}

API Key Authentication

Require an API key in request headers:
'routes' => [
    'enabled' => true,
    'prefix' => 'documentation',
    'middleware' => ['web', 'api.key'],
],
Example API Key Middleware:
// app/Http/Middleware/ValidateApiKey.php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class ValidateApiKey
{
    public function handle(Request $request, Closure $next)
    {
        $apiKey = $request->header('X-API-Key');
        $validKey = config('services.docs.api_key');

        if ($apiKey !== $validKey) {
            return response()->json([
                'error' => 'Invalid or missing API key'
            ], 401);
        }

        return $next($request);
    }
}
Usage:
curl -H "X-API-Key: your-secret-key" \
  http://localhost:8000/documentation/openapi.json

Available Routes

All these routes respect the configured middleware:
RouteMethodDescription
/documentation/openapi.{format}GETGenerate OpenAPI spec
/documentation/postmanGETGenerate Postman collection
/documentation/insomniaGETGenerate Insomnia workspace
/documentation/environments/{format?}GETGet all environments
Route Configuration Location: Routes are registered in the service provider when routes.enabled is true.

Security Middleware Mapping

OpenAPI Security Schemes

The package also allows you to map middleware to OpenAPI security schemes for route documentation:
// config/openapi.php
'middleware_security_map' => [
    'auth:sanctum' => ['BearerAuth'],
    'auth:api' => ['ApiKeyAuth'],
    'signed' => ['SignedUrl'],
],
How It Works: When generating OpenAPI specs, routes with these middleware automatically include the appropriate security requirements in the documentation. Example: If a route has auth:sanctum middleware:
Route::middleware(['auth:sanctum'])
    ->get('/api/users', [UserController::class, 'index']);
The OpenAPI spec will include:
{
  "paths": {
    "/api/users": {
      "get": {
        "security": [
          {"BearerAuth": []}
        ]
      }
    }
  }
}
Security Scheme Definitions: Define the schemes in your configuration:
'components' => [
    'securitySchemes' => [
        'BearerAuth' => [
            'type' => 'http',
            'scheme' => 'bearer',
            'bearerFormat' => 'JWT',
        ],
        'ApiKeyAuth' => [
            'type' => 'apiKey',
            'in' => 'header',
            'name' => 'X-API-Key',
        ],
    ],
],
Location: src/Services/OpenApiServices.php:1310-1327

Rate Limiting

Apply rate limiting to documentation routes:
'routes' => [
    'enabled' => true,
    'prefix' => 'documentation',
    'middleware' => ['web', 'throttle:60,1'], // 60 requests per minute
],
Custom Rate Limiter:
// app/Providers/RouteServiceProvider.php
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Support\Facades\RateLimiter;

public function boot()
{
    RateLimiter::for('docs', function (Request $request) {
        return Limit::perMinute(30)->by($request->ip());
    });
}
Then in configuration:
'middleware' => ['web', 'throttle:docs'],

CORS Configuration

If you need to allow cross-origin requests to documentation routes:
'routes' => [
    'enabled' => true,
    'prefix' => 'documentation',
    'middleware' => ['web', 'cors'],
],
CORS Configuration:
// config/cors.php
return [
    'paths' => ['documentation/*'],
    'allowed_methods' => ['GET', 'POST'],
    'allowed_origins' => ['*'],
    'allowed_headers' => ['*'],
    'max_age' => 3600,
];

Middleware Groups

Create a custom middleware group for documentation:
// app/Http/Kernel.php
protected $middlewareGroups = [
    'docs' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Session\Middleware\StartSession::class,
        'auth:sanctum',
        'throttle:60,1',
    ],
];
Use in configuration:
'routes' => [
    'enabled' => true,
    'prefix' => 'documentation',
    'middleware' => ['docs'],
],

Disabling HTTP Routes

If you prefer to generate specifications only via Artisan commands and not expose HTTP endpoints:
'routes' => [
    'enabled' => false,
],
This completely disables route registration. Use the Artisan command or Public API instead.

Testing Middleware

Feature Test Example

// tests/Feature/OpenApiRoutesTest.php
namespace Tests\Feature;

use Tests\TestCase;

class OpenApiRoutesTest extends TestCase
{
    /** @test */
    public function unauthenticated_users_cannot_access_documentation()
    {
        $response = $this->get('/documentation/openapi.json');

        $response->assertStatus(401);
    }

    /** @test */
    public function authenticated_users_can_access_documentation()
    {
        $user = User::factory()->create();

        $response = $this->actingAs($user, 'sanctum')
            ->get('/documentation/openapi.json');

        $response->assertStatus(200);
        $response->assertHeader('Content-Type', 'application/json');
    }

    /** @test */
    public function admin_users_can_access_documentation()
    {
        $admin = User::factory()->admin()->create();

        $response = $this->actingAs($admin, 'sanctum')
            ->get('/documentation/openapi.json');

        $response->assertStatus(200);
        $response->assertJsonStructure(['openapi', 'info', 'paths']);
    }
}

Best Practices

Production Environments:
  • Always require authentication for documentation routes in production
  • Consider IP whitelisting for internal tools
  • Apply rate limiting to prevent abuse
  • Use HTTPS for all documentation endpoints
Development Environments:
  • Use minimal middleware for easy access during development
  • Consider enabling routes only in non-production environments
  • Use .env variables to control route availability

HTTP Routes

Configure HTTP documentation endpoints

Artisan Commands

Generate docs via CLI

Security

Security best practices

Configuration

Full configuration reference

Build docs developers (and LLMs) love