Search by

andrii-hrechyn / auto-documentation

andrii-hrechyn

Auto generated documentation for laravel

Package info

github.com/andrii-hrechyn/auto-documentation

pkg:composer/andrii-hrechyn/auto-documentation

Statistics

Installs: 54

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v3.0.0-beta1 2026-08-29 18:46 UTC

This package is auto-updated.

Last update: 2026-08-29 18:54:04 UTC


README

Generate OpenAPI 3.1 documentation for Laravel APIs with fluent PHP builders, rendered with Redoc.

The typical endpoint is one chain:

Route::post('users.store')
    ->summary('Create user')
    ->fromFormRequest()                          // request body from validation rules, adds a 422 preset
    ->jsonResponse(UserSchema::make(), 201);

The URI, HTTP verb, {path} parameters, operationId, tag and the auth hint all come from your named Laravel route — you never describe what the framework already knows.

Requirements

  • PHP 8.2+
  • Laravel 11 or 12

Installation

composer require andrii-hrechyn/auto-documentation
php artisan auto-doc:install

The install command creates a docs/ folder (autoloaded as Docs\) with working examples:

docs
├── Components
│   ├── Parameters/ExampleParameter.php
│   └── Schemas/ExampleSchema.php
├── Paths
│   └── testPaths.php
└── info.php

Describing your API

Documentation files return values — no global state:

  • docs/info.php returns a configured AutoDoc builder;
  • every file in docs/Paths/ returns an array of Path objects.
// docs/info.php
return AutoDoc::make()
    ->info(Info::make('My API', '1.0.0'))
    ->servers([Server::make('https://api.example.com')])
    ->security(SanctumAuth::make())
    ->defaultSecurity(SanctumAuth::make());   // applied to every ->secure() operation

Route-first (recommended)

// docs/Paths/users.php
return [
    Route::get('users.show')
        ->summary('Get user')
        ->jsonResponse(UserSchema::make()),

    Route::post('users.store')
        ->summary('Create user')
        ->fromFormRequest()
        ->jsonResponse(UserSchema::make(), 201),
];

Explicit composition

Every shortcut expands into the same explicit object graph, which is always available:

return [
    Path::make('/orders/{order}')
        ->method(
            Method::get()
                ->summary('Get order')
                ->tag('orders')
                ->group('Shop')                      // Redoc x-tagGroups
                ->parameter(
                    Parameter::make('order', ParameterIn::PATH)
                        ->required()
                        ->schema(IntegerSchema::make())
                )
                ->response(SuccessfulResponse::make()->content([
                    Content::make('application/json')->schema(OrderSchema::make()),
                ]))
                ->secure()
        ),
];

Schemas

Full JSON Schema 2020-12 core: type unions (->nullable()), oneOf/anyOf/allOf/not with discriminators, additionalProperties, const, pattern, numeric and length constraints:

ObjectSchema::make([
    StringProperty::make('status')->enum(OrderStatus::class)->required(),
    NumberProperty::make('total')->minimum(0)->required(),
    StringProperty::make('note')->nullable(),
])->additionalProperties(false);

CompositeSchema::oneOf([CardPayment::make(), CashPayment::make()])
    ->discriminator('type');

Or infer a response schema from a real payload — the example is attached automatically and all keys become required:

->jsonResponse(Schema::fromExample([
    'id' => 1, 'name' => 'Ann', 'deleted_at' => null,
]))

Reusable schemas, parameters and responses extend the classes in AutoDocumentation\Components and are emitted under components with $ref automatically. Presets ship for common responses: UnauthorizedResponse (401), ForbiddenResponse (403), ValidationErrorResponse (422, Laravel error shape).

For API Resources, the recommended convention is one SchemaComponent per resource, referenced from every endpoint that returns it — the contract test below keeps the component honest against the real output.

Custom validation rules

fromFormRequest() maps standard Laravel rules out of the box. Register mappers for your own rules — by class for Rule objects, by name for string rules (rule arguments arrive in the matched string):

// e.g. in a service provider
ValidationRuleParser::extend(PhoneNumber::class,
    fn () => StringSchema::make()->pattern('^\+\d{10,15}$'));

ValidationRuleParser::extend('currency',
    fn (string $rule) => StringSchema::make()->enum(explode(',', Str::after($rule, ':'))));

A matched extension owns the field's schema; required and nullable handling still applies on top.

Generating and serving

php artisan auto-doc:generate   # writes storage/app/auto-docs/documentation.yaml

The Redoc UI is served at /api/doc (spec at /api/doc/spec) in the environments listed in the config. Set AUTO_DOCUMENTATION_GENERATE_ALWAYS=true locally to regenerate on every page load. Publish the config with:

php artisan vendor:publish --tag=auto-documentation

Keeping the documentation honest

Lint the spec structurally (missing responses, parameter/URI mismatches, dangling $refs, unregistered security schemes and more):

php artisan auto-doc:lint          # exit code 1 on errors
php artisan auto-doc:lint --strict # warnings fail too

Contract-test real responses against the documentation in your feature tests:

use AutoDocumentation\Testing\AssertsApiDoc;

$response = $this->getJson('/api/users/1');

$this->assertResponseMatchesApiDoc($response, '/api/users/{user}', 'get');

A response that drifts from its documented schema — wrong type, missing required field, undocumented status — fails the test with a field-level diff.

Testing

vendor/bin/pest

License

This library is licensed under the MIT License. See the LICENSE file for details.

Credits