zircote/swagger-php
Generate OpenAPI 3.0/3.1/3.2 docs from your PHP 8.2+ code using native attributes (preferred) or optional Doctrine annotations. Includes CLI and programmatic generation, parses phpdoc, provides helpful error reporting, and powers interactive API docs.
Pros:
boot() or service providers) or via CLI, offering flexibility.symfony/type-info for advanced type hints (e.g., generics, unions), reducing manual schema definitions in Laravel’s DTOs or request/response models.Cons:
Route::get()) to avoid duplication between route definitions and OpenAPI attributes.cache() helper).Laravel Ecosystem Fit:
Route definitions (e.g., #[OAT\Get(path: '/api/users')] alongside Route::get('/api/users', ...)). Use route model binding or middleware to sync metadata.#[OAT\RequestBody(content: new OAT\JsonContent(schema: new UserRequest()))]) to reuse request/response schemas.Generator instance in AppServiceProvider for programmatic access (e.g., app('openapi.generator')).php artisan openapi:generate).Dependencies:
zircote/swagger-php (v6.x) + symfony/type-info (required for type resolution).doctrine/annotations (legacy support; avoid unless migrating old code).rector/rector (for codebase modernization if adopting attributes).array<string, User>) may need explicit PHPDoc fallbacks if TypeInfoTypeResolver misbehaves.path in #[OAT\Get] matches Laravel’s route definitions to avoid inconsistencies.phpstan or psalm for validation.openapi-linter).// Cache for 1 hour
$openapi = Cache::remember('openapi-spec', 3600, fn() => $generator->generate());
#[AsOpenApi])?openapi-linter, custom scripts).#[OAT\Get], #[OAT\Post], etc., alongside Laravel’s Route:: methods. Example:
#[OAT\Get(path: '/users/{id}', summary: 'Get user by ID')]
public function show(User $user) { ... }
Request classes in #[OAT\RequestBody]:
#[OAT\RequestBody(content: new OAT\JsonContent(schema: new OAT\Schema(ref: '#/components/schemas/UserRequest')))]
#[OAT\Security(scheme: 'bearer')]).Route::get('/api/docs', function () {
return response($generator->generate(), 200, ['Content-Type' => 'application/yaml']);
});
/health).trait OpenApiAttributes {
#[OAT\Info(title: 'My API', version: '1.0')]
public function __construct() {}
}
zircote/swagger-php and symfony/type-info to composer.json.Generator in AppServiceProvider:
$this->app->singleton('openapi.generator', fn() => new Generator());
php artisan openapi:generate locally and validate output with openapi-linter.swagger-php v5.x (but lose OpenAPI 3.2 support).ext-json in v5.x).Generator and basic attributes (e.g., Info, Get).Request, Response) to use Laravel’s Request classes.swagger.yml to maintain.#[OAT\Get(path: '/...')]).#[ApiResource]).swagger-php (e.g., OpenAPI 3.2 features).Generator::generate() with debug: true to surface issues:
$generator->generate(['/app/Http/Controllers'], debug: true);
phpstan to catch attribute misconfigurations.laravel.io or r/laravelphp.cache() or Redis) for high-traffic APIs.post-deploy hook) and serve static filesHow can I help you explore Laravel packages today?