spatie/laravel-openapi-cli
Generate Laravel Artisan commands from any OpenAPI spec. Each endpoint becomes a CLI command with typed options for path/query params and request bodies. Configure base URL, auth, caching, output formats, redirects, and custom error handling—great with Laravel Zero.
Installation:
composer require spatie/laravel-openapi-cli
Publish the config (optional):
php artisan vendor:publish --provider="Spatie\OpenApiCli\OpenApiCliServiceProvider"
Define a Command:
Create a new Artisan command that extends Spatie\OpenApiCli\OpenApiCommand:
php artisan make:command GenerateApiDocs
Update the generated file:
<?php
namespace App\Console\Commands;
use Spatie\OpenApiCli\OpenApiCommand;
class GenerateApiDocs extends OpenApiCommand
{
protected $signature = 'api:docs {--spec= : Path to OpenAPI spec file}';
protected $description = 'Generate API documentation from OpenAPI spec';
}
First Use Case: Run the command with your OpenAPI spec file:
php artisan api:docs --spec=path/to/api-spec.yaml
This will generate a CLI output or file based on your spec.
config/openapi-cli.php (if published) for customizing output paths, formats, or behavior.Spatie\OpenApiCli\OpenApiCommand for extending functionality.Integrate with CI/CD: Add the command to your deployment pipeline to auto-generate API docs on every push:
# .github/workflows/docs.yml
jobs:
generate-docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-php@v2
- run: composer install
- run: php artisan api:docs --spec=api-spec.yaml --output=docs/openapi.json
Dynamic Spec Loading: Load OpenAPI specs from multiple files or directories:
// In your command class
public function handle()
{
$specs = [
'path/to/spec1.yaml',
'path/to/spec2.yaml',
];
foreach ($specs as $spec) {
$this->generateFromSpec($spec);
}
}
Custom Output Formats: Extend the command to output to Markdown, HTML, or other formats:
use Spatie\OpenApiCli\OpenApiCommand;
class GenerateMarkdownDocs extends OpenApiCommand
{
protected function generateOutput($spec)
{
// Custom logic to convert OpenAPI to Markdown
file_put_contents('docs/api.md', $this->convertToMarkdown($spec));
}
}
Pair with Laravel API Resources: Use the generated docs to validate your API responses:
// In your API resource
public function toArray($request)
{
// Ensure response matches OpenAPI schema
return [
'data' => $this->formatData(),
'meta' => ['schema' => 'UserSchema'], // Reference OpenAPI schema
];
}
Document Package APIs: If developing a Laravel package, use this to document its API endpoints:
// In your package's command
class PackageApiDocs extends OpenApiCommand
{
protected $signature = 'package:docs {--package= : Package name}';
protected function getSpecPath()
{
return base_path("packages/{$this->option('package')}/api-spec.yaml");
}
}
Versioned APIs: Generate docs for multiple API versions:
php artisan api:docs --spec=v1/api-spec.yaml --output=docs/v1
php artisan api:docs --spec=v2/api-spec.yaml --output=docs/v2
Spec File Paths:
base_path() or storage_path():
$specPath = base_path('api-spec.yaml');
Schema Validation:
use Spatie\OpenApiCli\OpenApiValidator;
if (!OpenApiValidator::validate($specPath)) {
$this->error('Invalid OpenAPI spec!');
return 1;
}
Output Overwriting:
--force flag or append timestamps to output files:
$outputPath = "docs/openapi-{$this->getTimestamp()}.json";
Verbose Mode: Enable debug output for troubleshooting:
php artisan api:docs --spec=api-spec.yaml --verbose
Log Spec Parsing: Log the parsed OpenAPI object for debugging:
$spec = $this->parseSpec($specPath);
\Log::debug('Parsed spec:', ['spec' => $spec]);
Custom Parsers:
Extend Spatie\OpenApiCli\Parsers\OpenApiParser to support additional spec formats:
class CustomParser extends OpenApiParser
{
public function parse($specPath)
{
// Custom parsing logic
return $this->transformToStandardFormat($rawSpec);
}
}
Hooks for Post-Processing:
Override generateOutput() to add metadata or transform data:
protected function generateOutput($spec)
{
$output = $this->convertToJson($spec);
$output['generated_at'] = now()->toIso8601String();
file_put_contents($this->outputPath, $output);
}
Event Listeners: Dispatch events for pre/post-processing:
use Spatie\OpenApiCli\Events\SpecProcessed;
protected function handle()
{
$spec = $this->parseSpec($this->option('spec'));
event(new SpecProcessed($spec));
$this->generateOutput($spec);
}
Default Output Path:
The default output path is storage/app/openapi.json. Override in config/openapi-cli.php:
'output_path' => storage_path('custom/openapi-docs'),
Spec File Extensions:
The package defaults to .yaml and .json. Add support for .yml or .openapi in config:
'supported_extensions' => ['yaml', 'yml', 'json', 'openapi'],
Environment-Specific Specs: Use Laravel's environment files to switch specs:
// In your command
$specPath = config('openapi.spec_path', base_path('api-spec.yaml'));
How can I help you explore Laravel packages today?