ronu/laravel-openapi-generator

Automatic OpenAPI 3.0.3 documentation generator for Laravel with Postman and Insomnia export support

Installs: 5

Dependents: 0

Suggesters: 0

Security: 0

Stars: 1

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/ronu/laravel-openapi-generator


README

Latest Version Total Downloads License Laravel PHP

The ultimate automatic API documentation generator for Laravel
Generate complete, production-ready documentation in three formats with 99% automation

🎯 Why This Package?

Most documentation tools require extensive annotations, complex configurations, or manual work. This package takes a different approach:

  • βœ… Zero Annotations - Extract everything from existing code
  • βœ… Three Formats - OpenAPI 3.0.3, Postman Collection v2.1, Insomnia Workspace v4
  • βœ… 99% Automatic - Intelligent extraction from FormRequests, Models, and Routes
  • βœ… Modular Support - First-class support for Nwidart modularized Laravel apps
  • βœ… Battle-Tested - Improved from 20% accuracy to 95%+ in production use
# One command to rule them all
php artisan openapi:generate --all

That's it. Your API documentation is ready in OpenAPI, Postman, and Insomnia formats.

πŸ“š Table of Contents

✨ Features

1. Multi-Format Export

Generate documentation in three industry-standard formats:

# OpenAPI 3.0.3 (JSON/YAML)
GET /documentation/openapi.json
GET /documentation/openapi.yaml

# Postman Collection v2.1
GET /documentation/postman

# Insomnia Workspace v4
GET /documentation/insomnia

2. Intelligent Metadata Extraction

From FormRequests:

// Your existing validation rules
class CreateUserRequest extends FormRequest
{
    public function rules()
    {
        return [
            'name' => 'required|string|max:255',
            'email' => 'required|email|unique:users',
            'age' => 'nullable|integer|min:18',
        ];
    }
}

// Automatically becomes
{
    "name": { "type": "string", "maxLength": 255 },
    "email": { "type": "string", "format": "email" },
    "age": { "type": "integer", "minimum": 18, "nullable": true }
}

From Models:

// Your existing Eloquent model
class User extends Model
{
    protected $fillable = ['name', 'email', 'status'];
    
    public function posts() {
        return $this->hasMany(Post::class);
    }
}

// Automatically extracts
- Field names and types
- Fillable attributes
- Relations (hasMany, belongsTo, etc.)
- Soft deletes detection

3. Modular Architecture

Perfect for applications organized with Nwidart Laravel Modules:

API Type (api, site, mobile)
  └─ Module (Security, Catalog, Sales)
      └─ Entity (users, products, orders)
          └─ Actions (list, show, create, update, delete, custom)

4. Smart Validation Rule Handling

Handles complex Laravel validation rules using a 4-strategy cascade:

// Even complex rules like this
Rule::unique($this->connection, 'table', 'field')
    ->ignore($this->route('id'))
    ->where(fn($q) => $q->where('status', 'active'))

// Are extracted correctly through
1. Normal instantiation
2. Mock dependency injection
3. Reflection without constructor
4. File parsing (fallback)

5. Environment Management

Generate pre-configured environments for different stages:

# Postman: 3 separate environment files
postman-env-artisan.json     # http://127.0.0.1:8000
postman-env-local.json       # http://localhost/project
postman-env-production.json  # https://api.production.com

# Insomnia: Integrated workspace with hierarchical environments
- Base Environment (shared variables)
  β”œβ”€ Artisan Environment
  β”œβ”€ Local Environment
  └─ Production Environment

6. Automatic Test Generation

Every request comes with tests:

// Postman tests
pm.test("Status is 200", function() { 
    pm.response.to.have.status(200); 
});
pm.test("Response has data", function() { 
    pm.expect(pm.response.json()).to.have.property('data'); 
});
pm.globals.set('last_user_id', pm.response.json().data.id);

// Insomnia tests (similar format)

7. API Type Filtering

Filter documentation by API type:

# Generate only API admin documentation
php artisan openapi:generate --all --api-type=api

# Generate for mobile and public site
php artisan openapi:generate --all --api-type=mobile --api-type=site

# Via URL
GET /documentation/openapi.json?api_type=api,mobile

πŸ“¦ Installation

Requirements

  • PHP 8.1 or higher
  • Laravel 10.x, 11.x, or 12.x
  • Composer 2.0+

Step 1: Install Package

composer require ronu/laravel-openapi-generator

The service provider will be automatically registered via Laravel's auto-discovery.

Step 2: Publish Configuration

# Publish configuration files
php artisan vendor:publish --tag=openapi-config

# Publish template files (optional, for customization)
php artisan vendor:publish --tag=openapi-templates

This creates:

  • config/openapi.php - Main configuration
  • config/openapi-docs.php - Documentation templates
  • config/openapi-tests.php - Test generation
  • resources/openapi/templates/ - Customizable templates (optional)

Step 3: Configure (Optional)

Edit config/openapi.php:

return [
    'info' => [
        'title' => env('APP_NAME', 'Laravel API'),
        'version' => '1.0.0',
        // ...
    ],
    
    'servers' => [
        [
            'url' => 'http://127.0.0.1:8000',
            'description' => 'Artisan server',
        ],
        // ...
    ],
    
    // Define your API types
    'api_types' => [
        'api' => [
            'prefix' => 'api',
            'folder_name' => 'API Admin',
            // ...
        ],
    ],
];

Step 4: Verify Installation

php artisan openapi:generate --help

You should see the command help with all available options.

πŸš€ Quick Start

Generate All Formats

php artisan openapi:generate --all

This generates:

  • storage/app/openapi.json
  • storage/app/openapi.yaml
  • storage/app/postman-collection.json
  • storage/app/postman-env-*.json (3 files)
  • storage/app/insomnia-workspace.json

Generate Specific Format

# Only OpenAPI JSON
php artisan openapi:generate

# Only OpenAPI YAML
php artisan openapi:generate --format=yaml

# Only Postman
php artisan openapi:generate --with-postman

# Only Insomnia
php artisan openapi:generate --with-insomnia

Access via HTTP

# OpenAPI
curl http://localhost:8000/documentation/openapi.json
curl http://localhost:8000/documentation/openapi.yaml

# Postman
curl http://localhost:8000/documentation/postman

# Insomnia
curl http://localhost:8000/documentation/insomnia

Import into Tools

Postman:

  1. Open Postman
  2. Import β†’ File β†’ Select postman-collection.json
  3. Import each postman-env-*.json as environments

Insomnia:

  1. Open Insomnia
  2. Import β†’ From File β†’ Select insomnia-workspace.json
  3. Everything is imported (spec + environments)

Swagger UI:

  1. Go to Swagger Editor
  2. File β†’ Import File β†’ Select openapi.yaml

πŸ“¦ Library Usage

If you prefer to use the generator as a library in your Laravel codebase, you can call the service directly:

use Ronu\OpenApiGenerator\OpenApiGenerator;

$generator = app(OpenApiGenerator::class);

$openApiSpec = $generator->generateOpenApi();
$postmanCollection = $generator->generatePostman();
$insomniaWorkspace = $generator->generateInsomnia();

The methods accept optional parameters for cache usage, API type filtering, and environment selection.

πŸ“‹ Documentation Formats

OpenAPI 3.0.3

Complete specification with:

  • Info and metadata
  • Server configurations
  • Security schemes (Bearer, API Key)
  • Paths with operations
  • Request/response schemas
  • Examples for all endpoints

Custom Format (Not Standard): This package uses a custom OpenAPI format where endpoints are grouped in a collections array instead of the standard paths object, optimized for modular Laravel applications.

Postman Collection v2.1

Includes:

  • Hierarchical folder structure (API Type β†’ Module β†’ Entity)
  • Pre-configured environments
  • Test scripts for response validation
  • Global variables for tracking (e.g., last_user_id)
  • Bearer token authentication

Insomnia Workspace v4

Features:

  • Design-first workspace
  • Integrated API specification
  • Environment hierarchy (Base + Sub-environments)
  • Request organization matching module structure
  • Variable inheritance

βš™οΈ Configuration

Main Configuration (config/openapi.php)

return [
    // API Information
    'info' => [
        'title' => env('APP_NAME'),
        'description' => 'Complete API documentation',
        'version' => '1.0.0',
        'contact' => [...],
        'license' => [...],
    ],

    // Server Environments
    'servers' => [
        ['url' => 'http://127.0.0.1:8000', 'description' => 'Artisan'],
        ['url' => env('APP_URL'), 'description' => 'Local'],
        ['url' => env('PRODUCTION_URL'), 'description' => 'Production'],
    ],

    // Security Schemes
    'security' => [
        'bearer_auth' => [
            'type' => 'http',
            'scheme' => 'bearer',
            'bearerFormat' => 'JWT',
        ],
        'api_key' => [
            'type' => 'apiKey',
            'in' => 'header',
            'name' => 'X-API-Key',
        ],
    ],

    // API Types (for filtering)
    'api_types' => [
        'api' => [
            'prefix' => 'api',
            'folder_name' => 'API Admin',
            'description' => 'Administration API',
        ],
        'mobile' => [
            'prefix' => 'mobile',
            'folder_name' => 'API Mobile',
            'description' => 'Mobile App API',
        ],
    ],

    // Nwidart Modules Support
    'nwidart' => [
        'enabled' => true,
        'path' => base_path('Modules'),
        'namespace' => 'Modules',
    ],

    // Middleware to Security Mapping
    'middleware_security' => [
        'auth:sanctum' => 'bearer_auth',
        'api_key' => 'api_key',
    ],
];

Documentation Templates (config/openapi-docs.php)

return [
    // Entity Configuration
    'entities' => [
        'users' => [
            'module' => 'Security',
            'singular' => 'user',
            'plural' => 'users',
            'model' => App\Models\User::class,
        ],
    ],

    // Custom Endpoint Documentation
    'custom_endpoints' => [
        'auth.login' => [
            'summary' => 'User Login',
            'description' => 'Authenticate user and return JWT token',
            'request_fields' => [
                'email' => 'User email address',
                'password' => 'User password',
            ],
        ],
    ],

    // Generic CRUD Templates
    'crud_templates' => [
        'list' => 'Retrieve paginated list of {entity_plural}',
        'show' => 'Retrieve details of a specific {entity_singular}',
        'create' => 'Create a new {entity_singular}',
        'update' => 'Update an existing {entity_singular}',
        'delete' => 'Delete a {entity_singular}',
    ],
];

Test Generation (config/openapi-tests.php)

return [
    // Test Templates for Actions
    'templates' => [
        'list' => ['status_200', 'json_response', 'has_data', 'is_array'],
        'show' => ['status_200', 'json_response', 'has_data', 'is_object'],
        'create' => ['status_201', 'json_response', 'save_to_global_var'],
        'update' => ['status_200', 'json_response'],
        'delete' => ['status_204_or_200'],
    ],

    // Reusable Test Snippets
    'snippets' => [
        'status_200' => "pm.test('Status is 200', function() { pm.response.to.have.status(200); });",
        'json_response' => "pm.test('Response is JSON', function() { pm.response.to.be.json; });",
        // ...
    ],

    // Custom Tests for Specific Endpoints
    'custom_tests' => [
        'auth.login' => [
            "pm.test('Response has token', function() { pm.expect(pm.response.json()).to.have.property('token'); });",
            "pm.globals.set('token', pm.response.json().token);",
        ],
    ],
];

πŸŽ“ Advanced Usage

Filtering by API Type

# Command line
php artisan openapi:generate --all --api-type=api --api-type=mobile

# Via HTTP
GET /documentation/openapi.json?api_type=api,mobile
GET /documentation/postman?api_type=site

Backward compatibility note: the legacy API type key movile is still accepted as a temporary alias for mobile in CLI flags and HTTP query parameters, but it is deprecated and may be removed in a future major release.

Specifying Environment

php artisan openapi:generate --all --environment=production

Custom Output Path

php artisan openapi:generate --output=/custom/path/openapi.json

Disable Cache

php artisan openapi:generate --no-cache

Combining Options

php artisan openapi:generate \
    --all \
    --api-type=api \
    --api-type=mobile \
    --environment=production \
    --no-cache

πŸ’‘ Examples

Example 1: Basic CRUD

Your Code:

// routes/api.php
Route::apiResource('users', UserController::class);

// app/Http/Requests/CreateUserRequest.php
class CreateUserRequest extends FormRequest
{
    public function rules()
    {
        return [
            'name' => 'required|string|max:255',
            'email' => 'required|email|unique:users',
        ];
    }
}

Generated Documentation:

{
  "paths": {
    "/api/users": {
      "post": {
        "summary": "Create a new user",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "name": { "type": "string", "maxLength": 255 },
                  "email": { "type": "string", "format": "email" }
                }
              }
            }
          }
        }
      }
    }
  }
}

Example 2: Custom Action

Your Code:

// config/openapi-docs.php
'custom_endpoints' => [
    'auth.login' => [
        'summary' => 'User Login',
        'description' => 'Authenticate user and return JWT token',
        'request_fields' => [
            'email' => 'User email address',
            'password' => 'User password',
        ],
    ],
],

Generated Documentation:

  • Automatically creates complete OpenAPI spec
  • Generates Postman request with tests
  • Creates Insomnia request
  • Includes in all formats

Example 3: Complex Validation

Your Code:

class UpdateUserRequest extends FormRequest
{
    public function rules()
    {
        return [
            'email' => [
                'sometimes',
                'email',
                Rule::unique('users')->ignore($this->user),
            ],
            'password' => [
                'sometimes',
                Password::min(8)->mixedCase()->numbers(),
            ],
        ];
    }
}

Result:

  • Correctly extracts email as unique (ignoring current user)
  • Extracts password requirements (min 8, mixed case, numbers)
  • Marks both as optional (sometimes)

πŸ› Troubleshooting

Issue: "Class not found" errors

composer dump-autoload
php artisan clear-compiled
php artisan cache:clear

Issue: Empty request bodies

Problem: Generated requests show empty {} body

Solution:

  1. Verify FormRequest has rules() method
  2. Check scenario detection in middleware
  3. Enable debug mode:
// config/openapi.php
'debug' => true,

Issue: Missing modules in documentation

Problem: Nwidart modules not appearing

Solution:

# Verify modules are enabled
php artisan module:list

# Check config
// config/openapi.php
'nwidart' => [
    'enabled' => true,
    'path' => base_path('Modules'),
],

Issue: Variables not working in Insomnia

Problem: {{ _.token }} shows as literal text

Solution: Verify environment structure has _type: environment in JSON

Issue: Routes not accessible

Problem: HTTP routes not working

Solution: Check if routes are enabled:

// config/openapi.php
'routes' => [
    'enabled' => true,
    'prefix' => 'documentation',
],

For more troubleshooting, see INSTALLATION.md.

🀝 Contributing

Contributions are welcome! Please follow these steps:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Development Setup

git clone https://github.com/ronu/laravel-openapi-generator.git
cd laravel-openapi-generator
composer install
vendor/bin/phpunit

Code Style

vendor/bin/php-cs-fixer fix

Static Analysis

vendor/bin/phpstan analyse

πŸ“ License

This package is open-sourced software licensed under the MIT license.

πŸ™ Credits

  • Author: charlietyn (charlietyn@gmail.com)
  • Inspired by: Real-world needs in production Laravel applications
  • Special thanks: Laravel community and all contributors

πŸ“ž Support

πŸ—ΊοΈ Roadmap

  • Swagger UI integration
  • ReDoc theme support
  • GraphQL endpoint detection
  • Custom rule library expansion
  • Performance optimizations with caching
  • Multi-language support
  • Laravel 13 support

⭐ Show Your Support

If this package helped you, please consider:

  • ⭐ Starring the repository
  • πŸ› Reporting bugs
  • πŸ’‘ Suggesting features
  • 🀝 Contributing code
  • πŸ“’ Sharing with others

Made with ❀️ for the Laravel community
From hours of manual documentation to minutes of automation