{"id":15190356,"url":"https://github.com/andrii-hrechyn/auto-documentation","last_synced_at":"2026-02-06T16:33:43.479Z","repository":{"id":81108524,"uuid":"605599739","full_name":"andrii-hrechyn/auto-documentation","owner":"andrii-hrechyn","description":"Auto Documentation is a library for generating API documentation for Laravel.","archived":false,"fork":false,"pushed_at":"2026-02-01T13:47:09.000Z","size":309,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-01T23:25:37.086Z","etag":null,"topics":["documentaion","laravel","laravel10","openapi","openapi3","redoc","redocly"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/andrii-hrechyn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-02-23T14:00:16.000Z","updated_at":"2026-02-01T13:47:14.000Z","dependencies_parsed_at":null,"dependency_job_id":"b5dbfc64-a183-4827-b87d-43ea0dc3d238","html_url":"https://github.com/andrii-hrechyn/auto-documentation","commit_stats":{"total_commits":10,"total_committers":2,"mean_commits":5.0,"dds":0.09999999999999998,"last_synced_commit":"3a559f77e7d1f379d0d446e30c85fae09ccb5373"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/andrii-hrechyn/auto-documentation","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrii-hrechyn%2Fauto-documentation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrii-hrechyn%2Fauto-documentation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrii-hrechyn%2Fauto-documentation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrii-hrechyn%2Fauto-documentation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andrii-hrechyn","download_url":"https://codeload.github.com/andrii-hrechyn/auto-documentation/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrii-hrechyn%2Fauto-documentation/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29168537,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-06T16:33:35.550Z","status":"ssl_error","status_checked_at":"2026-02-06T16:33:30.716Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["documentaion","laravel","laravel10","openapi","openapi3","redoc","redocly"],"created_at":"2024-09-27T20:22:10.118Z","updated_at":"2026-02-06T16:33:43.470Z","avatar_url":"https://github.com/andrii-hrechyn.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Auto Documentation\n\nA fluent, object-oriented library for generating OpenAPI 3.1.0 documentation in Laravel applications.\n\n![PHP 8.3+](https://img.shields.io/badge/PHP-8.3%2B-blue)\n![Laravel 7-11](https://img.shields.io/badge/Laravel-7--11-red)\n![License: MIT](https://img.shields.io/badge/License-MIT-green)\n\n## Introduction\n\nAuto Documentation lets you describe your API endpoints as PHP classes using a fluent builder API. The library auto-discovers your documentation classes, resolves reusable components via `$ref`, and generates a complete OpenAPI 3.1.0 specification as YAML — viewable through a built-in Redoc UI.\n\nKey features:\n\n- **Fluent PHP API** — describe paths, schemas, parameters, and responses with method chaining\n- **Auto-discovery** — path and component classes are automatically found and registered\n- **Reusable components** — schemas, parameters, requests, and responses are deduplicated via `$ref`\n- **Laravel integration** — built-in artisan commands, route-based request body extraction, Sanctum auth support\n- **OpenAPI 3.1.0** compliant output\n\n## Requirements\n\n- PHP 8.3+\n- Laravel 7, 8, 9, 10, or 11\n\n## Installation\n\nInstall via Composer:\n\n```bash\ncomposer require andrii-hrechyn/auto-documentation\n```\n\nRun the install command to scaffold the `docs/` folder with examples and register the `Docs\\\\` namespace in your `composer.json` autoload:\n\n```bash\nphp artisan auto-doc:install\n```\n\nThis creates the following structure:\n\n```\ndocs/\n├── Components/\n│   ├── Parameters/\n│   ├── Requests/\n│   ├── Responses/\n│   ├── Schemas/\n│   └── Security/\n├── Paths/\n└── Documentation.php\n```\n\n## Quick Start\n\n### 1. Define your Documentation class\n\n```php\n// docs/Documentation.php\nnamespace Docs;\n\nuse AutoDocumentation\\BaseDocumentation;\nuse AutoDocumentation\\Info;\n\nclass Documentation extends BaseDocumentation\n{\n    protected function info(): Info\n    {\n        return Info::make('My API', '1.0.0')\n            -\u003edescription('API documentation');\n    }\n}\n```\n\n### 2. Create a path component\n\n```php\n// docs/Paths/UsersPath.php\nnamespace Docs\\Paths;\n\nuse AutoDocumentation\\Base\\PathComponent;\nuse AutoDocumentation\\Paths\\Method;\nuse AutoDocumentation\\Paths\\Path;\nuse AutoDocumentation\\Properties\\IntegerProperty;\nuse AutoDocumentation\\Properties\\StringProperty;\n\nclass UsersPath extends PathComponent\n{\n    public function path(): Path\n    {\n        return $this-\u003emake('users');\n    }\n\n    public function get(Method $method): Method\n    {\n        return $method\n            -\u003eoperationId('listUsers')\n            -\u003esummary('List all users')\n            -\u003etag('Users')\n            -\u003ejsonResponse([\n                IntegerProperty::make('id')-\u003eexample(1),\n                StringProperty::make('name')-\u003eexample('John'),\n                StringProperty::make('email')-\u003eformat('email'),\n            ]);\n    }\n}\n```\n\n### 3. Generate documentation\n\n```bash\nphp artisan auto-doc:generate\n```\n\nThe specification is written to `storage/app/auto-docs/documentation.yaml` and served at `/api/doc`.\n\n## Documentation Class\n\nThe `Documentation` class extends `BaseDocumentation` and serves as the entry point for your API spec. It has one required method and several optional ones.\n\n### Info (required)\n\n```php\nprotected function info(): Info\n{\n    return Info::make('Blog Platform API', '2.0.0')\n        -\u003edescription('API documentation for the Blog Platform')\n        -\u003etermsOfService('https://example.com/terms')\n        -\u003econtact(\n            (new Contact())\n                -\u003ename('API Support')\n                -\u003eemail('support@example.com')\n                -\u003eurl('https://example.com/support')\n        )\n        -\u003elicense(\n            License::make('MIT')\n                -\u003eurl('https://opensource.org/licenses/MIT')\n        );\n}\n```\n\n### Servers\n\n```php\nprotected function servers(): array\n{\n    return [\n        Server::make('https://api.example.com/{version}')\n            -\u003edescription('Production server')\n            -\u003evariable(\n                Variable::make('version', 'v2')\n                    -\u003eenum(['v1', 'v2'])\n                    -\u003edescription('API version')\n            ),\n    ];\n}\n```\n\n### Default Security\n\nSet a global security scheme applied to all operations:\n\n```php\nprotected function defaultSecuritySchema(): ?SecurityRequirement\n{\n    return SanctumAuth::make();\n}\n```\n\n### Tags, Extensions \u0026 Tag Groups\n\nUse `additionalOptions()` to define tags, vendor extensions, external docs, and tag groups:\n\n```php\npublic function additionalOptions(): void\n{\n    $this-\u003eopenApi-\u003eexternalDocs(\n        ExternalDocs::make('https://example.com/docs')\n            -\u003edescription('Full developer documentation')\n    );\n\n    $this-\u003eopenApi-\u003etag(\n        (new Tag())-\u003ename('Users')-\u003edescription('User management operations')\n    );\n    $this-\u003eopenApi-\u003etag(\n        (new Tag())-\u003ename('Posts')-\u003edescription('Blog post operations')\n    );\n\n    // Vendor extensions\n    $this-\u003eopenApi-\u003eextension('x-api-id', 'my-api');\n\n    // Tag groups (Redoc x-tagGroups extension)\n    $this-\u003eopenApi-\u003eextension('x-tagGroups', [\n        new Group('Content', ['Posts', 'Comments']),\n        new Group('Access', ['Users', 'Auth']),\n    ]);\n}\n```\n\n## Paths\n\n### PathComponent (recommended)\n\nPath components are auto-discovered from the `docs/Paths/` directory. Extend `PathComponent` and define HTTP methods as class methods:\n\n```php\nclass PostPath extends PathComponent\n{\n    public function path(): Path\n    {\n        return $this-\u003emake('posts/{postId}')\n            -\u003eparameter(\n                Parameter::make('postId', ParameterIn::PATH)\n                    -\u003edescription('The post ID')\n                    -\u003erequired()\n                    -\u003eexample(42)\n            );\n    }\n\n    public function get(Method $method): Method\n    {\n        return $method\n            -\u003eoperationId('getPost')\n            -\u003esummary('Get a post by ID')\n            -\u003etag('Posts')\n            -\u003eresponse(\n                SuccessfulResponse::make()-\u003econtent([\n                    ApplicationJson::make(PostSchema::make()),\n                ])\n            );\n    }\n\n    public function delete(Method $method): Method\n    {\n        return $method\n            -\u003eoperationId('deletePost')\n            -\u003esummary('Delete a post')\n            -\u003etag('Posts')\n            -\u003eresponse(NoContentResponse::make());\n    }\n}\n```\n\nSupported HTTP methods: `get`, `post`, `put`, `patch`, `delete`, `head`, `options`. Only define the methods your endpoint supports — the rest are omitted automatically.\n\n### AuthPathComponent\n\nExtends `PathComponent` and automatically applies Sanctum security to all methods:\n\n```php\nclass AuthPath extends AuthPathComponent\n{\n    public function path(): Path\n    {\n        return $this-\u003emake('auth/login');\n    }\n\n    public function post(Method $method): Method\n    {\n        return $method\n            -\u003eoperationId('login')\n            -\u003esummary('Authenticate and receive a token')\n            -\u003etag('Auth')\n            -\u003ejsonRequest([\n                StringProperty::make('email')-\u003erequired()-\u003eformat('email'),\n                StringProperty::make('password')-\u003erequired()-\u003eformat('password'),\n            ])\n            -\u003ejsonResponse([\n                StringProperty::make('token')-\u003eexample('1|abc123def456'),\n                StringProperty::make('token_type')-\u003edefault('Bearer'),\n            ]);\n    }\n}\n```\n\n### Route-based paths\n\nReference existing Laravel routes by name and extract request bodies from form request validation rules:\n\n```php\nRoute::make('posts.store', 'Create a new post')\n    -\u003etag('Posts')\n    -\u003erequestBodyFromRequestClass()\n    -\u003esuccessfulResponse(PostSchema::make())\n    -\u003esecure();\n```\n\n### Method options\n\nMethods support the full OpenAPI operation spec:\n\n```php\n$method\n    -\u003eoperationId('updatePost')\n    -\u003esummary('Update a post')\n    -\u003edescription('Full description here')\n    -\u003etag('Posts')                                      // or -\u003etag((new Tag())-\u003ename('Posts'))\n    -\u003edeprecated()\n    -\u003eexternalDocs(ExternalDocs::make('https://...'))\n    -\u003eextension('x-sunset', '2025-12-31')\n    -\u003esecurity(ApiKeyAuth::make())                      // per-operation security override\n    -\u003erequest($request)\n    -\u003eresponse($response);\n```\n\n## Properties\n\nProperties describe individual fields within schemas and request/response bodies. All properties use `make(string $name)` and support method chaining.\n\n| Class | Type | Extra methods |\n|---|---|---|\n| `StringProperty` | `string` | `minLength()`, `maxLength()` |\n| `IntegerProperty` | `integer` | `minimum()`, `maximum()` |\n| `NumberProperty` | `number` | `minimum()`, `maximum()` |\n| `BooleanProperty` | `boolean` | — |\n| `ArrayProperty` | `array` | `minItems()`, `maxItems()` |\n| `ObjectProperty` | `object` | — |\n| `DateTimeProperty` | `string` (format: `date-time`) | `minLength()`, `maxLength()` |\n| `FileProperty` | `string` (format: `binary`) | `minLength()`, `maxLength()` |\n\nCommon methods available on all properties: `required()`, `description()`, `example()`, `enum()`, `default()`, `format()`, `title()`, `extension()`.\n\n```php\n// Examples\nStringProperty::make('title')-\u003erequired()-\u003emaxLength(255)-\u003eexample('My Post'),\nIntegerProperty::make('id')-\u003eexample(42),\nStringProperty::make('status')-\u003eenum(['draft', 'published', 'archived'])-\u003edefault('draft'),\nDateTimeProperty::make('created_at'),\nArrayProperty::make('tag_ids', IntegerSchema::make()),\n```\n\n## Schemas\n\nSchemas define the structure of data objects and are used inside properties, request bodies, and responses.\n\n### ObjectSchema\n\n```php\nObjectSchema::make([\n    IntegerProperty::make('id')-\u003eexample(1),\n    StringProperty::make('name')-\u003erequired(),\n    StringProperty::make('email')-\u003eformat('email'),\n]);\n```\n\n### ArraySchema\n\n```php\n// Array of primitives\nArraySchema::make(IntegerSchema::make())-\u003eminItems(1);\n\n// Array of objects\nArraySchema::make(\n    ObjectSchema::make([\n        StringProperty::make('title'),\n    ])\n);\n```\n\n### Primitive Schemas\n\n`StringSchema`, `IntegerSchema`, `NumberSchema`, `BooleanSchema` — used as items for `ArraySchema` or `ArrayProperty`.\n\n## Reusable Components\n\nComponents are self-registering classes that output `$ref` references in the generated spec. Extend the appropriate base class and implement the `content()` method.\n\n### SchemaComponent\n\n```php\nclass PostSchema extends SchemaComponent\n{\n    public function content(): ObjectSchema\n    {\n        return $this-\u003eschema([\n            IntegerProperty::make('id')-\u003eexample(42),\n            StringProperty::make('title')-\u003erequired()-\u003emaxLength(255)-\u003eexample('My First Post'),\n            StringProperty::make('body')-\u003erequired(),\n            StringProperty::make('status')-\u003eenum(['draft', 'published', 'archived'])-\u003edefault('draft'),\n            IntegerProperty::make('author_id')-\u003eexample(1),\n            ArrayProperty::make('comment_ids', IntegerSchema::make()),\n            DateTimeProperty::make('published_at'),\n            DateTimeProperty::make('created_at'),\n        ])-\u003eextension('x-model', 'App\\\\Models\\\\Post');\n    }\n}\n```\n\nUsage: `PostSchema::make()` — returns a `$ref` to `#/components/schemas/PostSchema`.\n\n### ParameterComponent\n\n```php\nclass PageParameter extends ParameterComponent\n{\n    public function content(): Parameter\n    {\n        return $this-\u003eparameter('page', ParameterIn::QUERY)\n            -\u003edescription('Page number for pagination')\n            -\u003eexample(1);\n    }\n}\n```\n\nUsage: `PageParameter::make()` — returns a `$ref` to `#/components/parameters/PageParameter`.\n\n### RequestComponent\n\n```php\nclass CreatePostRequest extends RequestComponent\n{\n    public function content(): Request\n    {\n        return $this-\u003erequest()\n            -\u003erequired()\n            -\u003edescription('Data for creating a new blog post')\n            -\u003econtent([\n                ApplicationJson::make(\n                    ObjectSchema::make([\n                        StringProperty::make('title')-\u003erequired()-\u003emaxLength(255),\n                        StringProperty::make('body')-\u003erequired(),\n                        StringProperty::make('status')-\u003eenum(['draft', 'published'])-\u003edefault('draft'),\n                    ])\n                ),\n            ]);\n    }\n}\n```\n\n### ResponseComponent\n\n```php\nclass UnauthorizedResponse extends ResponseComponent\n{\n    public function content(): Response\n    {\n        return $this-\u003eresponse(401)\n            -\u003edescription('Unauthenticated')\n            -\u003econtent([\n                ApplicationJson::make(ErrorSchema::make()),\n            ]);\n    }\n}\n```\n\n## Parameters\n\nParameters are created with a name and location (`ParameterIn` enum):\n\n```php\nuse AutoDocumentation\\Enums\\ParameterIn;\n\n// Inline parameter\nParameter::make('postId', ParameterIn::PATH)\n    -\u003edescription('The post ID')\n    -\u003erequired()\n    -\u003eexample(42);\n\n// Query parameter\nParameter::make('search', ParameterIn::QUERY)\n    -\u003edescription('Search term')\n    -\u003eexample('laravel');\n\n// Header parameter\nParameter::make('Accept-Language', ParameterIn::HEADER)\n    -\u003edescription('Preferred language')\n    -\u003eexample('en-US');\n\n// Cookie parameter\nParameter::make('session', ParameterIn::COOKIE)\n    -\u003edescription('Session identifier');\n```\n\nAttach parameters to a path:\n\n```php\n$this-\u003emake('posts')\n    -\u003eparameter(PageParameter::make())\n    -\u003eparameter(PerPageParameter::make());\n```\n\n## Request Bodies\n\n### JSON request (shorthand)\n\nUse `jsonRequest()` on a method for a quick JSON body:\n\n```php\n$method-\u003ejsonRequest([\n    StringProperty::make('title')-\u003erequired()-\u003emaxLength(255),\n    StringProperty::make('body')-\u003erequired(),\n]);\n```\n\nOr pass a schema directly:\n\n```php\n$method-\u003ejsonRequest(\n    ObjectSchema::make([\n        StringProperty::make('title')-\u003erequired(),\n    ])\n);\n```\n\n### Multipart/form-data\n\nFor file uploads, use `MultipartFormData` content type:\n\n```php\n$method-\u003erequest(\n    Request::make()\n        -\u003erequired()\n        -\u003econtent([\n            MultipartFormData::make(FileUploadSchema::make()),\n        ])\n);\n```\n\n### From Laravel validation rules\n\nWhen using `Route::make()`, extract the request body directly from a form request class:\n\n```php\nRoute::make('posts.store', 'Create a post')\n    -\u003erequestBodyFromRequestClass();\n```\n\nThis inspects the controller method's type-hinted `Request` class and converts its `rules()` to an OpenAPI schema.\n\n## Responses\n\n### SuccessfulResponse\n\n```php\nSuccessfulResponse::make()          // 200\nSuccessfulResponse::make(201)       // 201\n    -\u003edescription('Post created')\n    -\u003econtent([\n        ApplicationJson::make(PostSchema::make()),\n    ]);\n```\n\n### NoContentResponse\n\n```php\nNoContentResponse::make();          // 204\n```\n\n### JSON response (shorthand)\n\n```php\n$method-\u003ejsonResponse([\n    StringProperty::make('token')-\u003eexample('abc123'),\n    StringProperty::make('token_type')-\u003edefault('Bearer'),\n]);\n```\n\n### Custom responses\n\n```php\nResponse::make(422)\n    -\u003ename('ValidationError')\n    -\u003edescription('Validation failed')\n    -\u003econtent([\n        ApplicationJson::make(ErrorSchema::make()),\n    ]);\n```\n\n## Security\n\n### Built-in: SanctumAuth\n\n```php\nuse AutoDocumentation\\Security\\SanctumAuth;\n\n// As global default\nprotected function defaultSecuritySchema(): ?SecurityRequirement\n{\n    return SanctumAuth::make();\n}\n\n// Per-operation\n$method-\u003esecurity(SanctumAuth::make());\n```\n\n### HTTP Security Scheme\n\n```php\nHttpSecurityScheme::make('bearer')\n    -\u003ebearerFormat('JWT')\n    -\u003edescription('JWT Bearer token');\n```\n\n### API Key\n\n```php\nuse AutoDocumentation\\Enums\\ApiKeySecuritySchemeIn;\n\nApiKeySecurityScheme::make('X-API-Key', ApiKeySecuritySchemeIn::HEADER)\n    -\u003edescription('API key passed in the X-API-Key header');\n```\n\n### OpenID Connect\n\n```php\nOpenIdConnectSecurityScheme::make('https://auth.example.com/.well-known/openid-configuration')\n    -\u003edescription('OpenID Connect');\n```\n\n### Custom security component\n\nCreate a reusable security requirement:\n\n```php\nclass ApiKeyAuth extends SecurityRequirement\n{\n    public function content(): SecurityScheme\n    {\n        return ApiKeySecurityScheme::make('X-API-Key', ApiKeySecuritySchemeIn::HEADER)\n            -\u003edescription('API key passed in the X-API-Key header');\n    }\n}\n```\n\nUse it globally or per-operation:\n\n```php\n// Global\nprotected function defaultSecuritySchema(): ?SecurityRequirement\n{\n    return ApiKeyAuth::make();\n}\n\n// Per-operation override\n$method-\u003esecurity(ApiKeyAuth::make());\n```\n\n## Configuration\n\nPublish the config file with `php artisan vendor:publish --tag=auto-documentation-config`.\n\n| Option | Default | Description |\n|---|---|---|\n| `generate_always` | `false` | Auto-regenerate the spec on every page load (dev only) |\n| `environment` | `['local', 'development']` | Environments where documentation routes are registered |\n| `routes.documentation` | `api/doc` | URL path for the Redoc UI |\n| `routes.specification` | `api/doc/spec` | URL path for the raw OpenAPI YAML |\n| `paths.source` | `base_path('docs')` | Directory containing your documentation classes |\n| `paths.generated-doc` | `storage_path('app/auto-docs')` | Directory where the generated YAML is stored |\n\nEnvironment variable `AUTO_DOCUMENTATION_GENERATE_ALWAYS` controls the `generate_always` option. `AUTO_DOCUMENTATION_SOURCE` controls the source docs path.\n\n## Generation\n\n### Artisan command\n\n```bash\nphp artisan auto-doc:generate\n```\n\nGenerates `documentation.yaml` from your `Documentation` class and all discovered path components.\n\n### Auto-regeneration\n\nSet `generate_always` to `true` (or `AUTO_DOCUMENTATION_GENERATE_ALWAYS=true` in `.env`) to regenerate the spec on every documentation page load. Useful during development.\n\n### Routes\n\n| Route | Description |\n|---|---|\n| `/api/doc` | Redoc documentation UI |\n| `/api/doc/spec` | Raw OpenAPI YAML specification |\n\nRoutes are only registered in the environments listed in the `environment` config option.\n\n## License\n\nThis library is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.\n\n## Credits\n\n- Developer: Andriy Hrechyn\n- Email: andriy.hrechyn@gmail.com\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandrii-hrechyn%2Fauto-documentation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandrii-hrechyn%2Fauto-documentation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandrii-hrechyn%2Fauto-documentation/lists"}