packages
Laravel Data OpenAPI Generator: generate OpenAPI docs from Laravel routes and Data objects
nicoandra/laravel-data-openapi-generator is a package I published to generate an OpenAPI specification directly from Laravel routes and Spatie Laravel Data objects.
The package exists for a simple reason: API documentation drifts fast when the OpenAPI file lives far away from the code that actually handles requests and responses.
What problem it solves
If a Laravel project already uses:
- controller methods as the API entry points
Dataclasses for requests and responses- route model and route parameter conventions
then most of the useful API contract is already in the codebase.
This package turns that contract into an OpenAPI document without forcing you to maintain a separate hand-written schema for every endpoint.
What it generates
The generator reads your routes, controller signatures, and Data classes to build:
- OpenAPI paths from Laravel routes
- request bodies and response schemas from
Dataobjects - route parameters from controller method signatures
- schema descriptions and examples from PHP attributes
- security requirements and
401/403responses from configured middleware
It also exposes:
GET /api/openapifor Swagger UIGET /api/openapi.jsonfor the generated JSON document
Installation
composer require nicoandra/laravel-data-openapi-generator
php artisan vendor:publish --tag=openapi-generator-config
php artisan openapi:generate
By default, the generated spec is written to resources/api/openapi.json.
Why the package is useful
The strongest part of this approach is that it treats your Laravel code as the source of truth.
That means you can enrich the generated documentation with attributes such as:
#[Summary(...)]#[Description(...)]#[Example(...)]#[IgnoreFromOpenApi]#[HttpResponseStatus(...)]#[CustomContentType(...)]#[Tags(...)]
Instead of maintaining parallel documentation, you annotate the same classes and controller methods the application already uses.
Example
<?php
namespace App\Data;
use NicoAndra\OpenApiGenerator\Attributes\Example;
use Spatie\LaravelData\Attributes\FromRouteParameter;
use Spatie\LaravelData\Data;
class CreatePostData extends Data
{
public function __construct(
#[FromRouteParameter('author')]
public int $authorId,
#[Example('How to keep docs in sync with code')]
public string $title,
public string $body,
) {}
}
<?php
namespace App\Http\Controllers;
use App\Data\CreatePostData;
use App\Data\PostData;
use NicoAndra\OpenApiGenerator\Attributes\Description;
use NicoAndra\OpenApiGenerator\Attributes\Summary;
class PostController
{
#[Summary('Create a post')]
#[Description('Creates a post for an author and returns the stored resource')]
public function store(CreatePostData $data): PostData
{
// ...
}
}
With a route like this:
Route::post('/api/authors/{author}/posts', [PostController::class, 'store']);
the package can derive the endpoint shape, request schema, and response schema from code that already exists.