packages

Laravel Data OpenAPI Generator: generate OpenAPI docs from Laravel routes and Data objects

June 10, 2026

laravel openapi php packagist spatie-laravel-data

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
  • Data classes 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 Data objects
  • route parameters from controller method signatures
  • schema descriptions and examples from PHP attributes
  • security requirements and 401 / 403 responses from configured middleware

It also exposes:

  • GET /api/openapi for Swagger UI
  • GET /api/openapi.json for 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.

Where to find it