Download the PHP package jkbennemann/laravel-api-documentation without Composer
On this page you can find all versions of the php package jkbennemann/laravel-api-documentation. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download jkbennemann/laravel-api-documentation
More information about jkbennemann/laravel-api-documentation
Files in jkbennemann/laravel-api-documentation
Package laravel-api-documentation
Short Description Zero-config OpenAPI 3.1.0 documentation generator for Laravel with plugin system, $ref deduplication, and multi-source analysis.
License MIT
Homepage https://github.com/jkbennemann/laravel-api-documentation
Informations about the package laravel-api-documentation
Laravel API Documentation
A zero-configuration OpenAPI 3.1.0 documentation generator for Laravel. Analyzes your routes, controllers, form requests, and responses using AST parsing, PHP reflection, and optional runtime capture - then outputs a complete, valid OpenAPI spec without you writing a single annotation.
Requirements
- PHP 8.2+
- Laravel 10, 11, or 12
Installation
Publish the configuration file (optional):
Generate your documentation:
That's it. The package discovers your routes, analyzes your code, and writes an OpenAPI 3.1.0 spec to storage/app/public/api-documentation.json.
Table of Contents
- How It Works
- Quick Start
- Commands
- Runtime Capture
- PHP Attributes
- Configuration
- Tags & Documentation
- Documentation Viewers
- Output Formats
- Plugin System
- Built-in Plugins
- Creating a Plugin
- Integrations
- CI/CD Integration
- Security
- Credits
- License
How It Works
The package uses a 5-layer pipeline to generate documentation:
What Gets Analyzed Automatically
Requests:
FormRequestvalidation rules (types, formats, min/max, enums, patterns, required/optional)- Inline
$this->validate()andValidator::make()calls $request->get(),$request->query(),$request->integer()method calls in controller bodies- File upload detection (
file,imagerules) with automaticmultipart/form-datacontent type - Nested parameter structures (
user.profile.name)
Responses:
- Return type declarations (
JsonResource,JsonResponse,ResourceCollection, SpatieData) - Controller method body analysis (traces
response()->json([...])return statements) - PHPDoc
@returntypes including union types (UserData|AdminDataproducesoneOf) - Abort statements (
abort(404),abort_if()) for error responses - Paginated responses with
data,meta, andlinksstructure JsonResource::toArray()analysis (property types,$this->when(),$this->whenLoaded(),$this->merge())
Query Parameters:
FormRequestrules on GET routes become query parameters- PHPDoc
@queryParamannotations - Pagination detection (
paginate(),simplePaginate(),cursorPaginate()) addspage/per_pageparams
Errors:
FormRequestpresence adds422validation errorauth/sanctummiddleware adds401unauthorizedGate/authorizecalls add403forbidden- Route model binding adds
404not found throttlemiddleware adds429rate limited- Custom exception handler analysis for app-specific error schemas
Security:
auth:sanctum,auth:api,jwt.authmiddleware detected as Bearer token auth- OAuth scopes extracted from
scope:andscopes:middleware - Sanctum abilities extracted from
ability:andabilities:middleware
Quick Start
Zero-Config (Static Analysis)
For a standard Laravel API, no configuration is needed:
The package reads your routes, controllers, form requests, and resources to produce a spec. This typically achieves ~70% schema accuracy, depending on how explicitly typed your code is.
With Runtime Capture (Recommended)
Enable runtime capture to use real API responses from your test suite, bringing accuracy to 95%+:
1. Add to phpunit.xml:
2. Register the middleware in your test setup (e.g., TestCase.php or a service provider used during testing):
3. Run your tests, then generate:
The middleware captures request/response data to .schemas/responses/ during test runs. The generator merges this with static analysis to produce accurate schemas with real examples. See Runtime Capture for details.
With Attributes (Precision)
For routes where auto-detection falls short (proxy controllers, dynamic responses), add PHP 8 attributes:
Commands
api:generate - Generate Documentation
| Option | Description |
|---|---|
--format=json |
Output format: json, yaml, or postman |
--domain= |
Generate for a specific domain only |
--route= |
Generate for a single route URI (for debugging) |
--method=GET |
HTTP method when using --route |
--dev |
Include development servers in output |
--clear-cache |
Clear AST cache before generating |
--verbose-analysis |
Show analyzer decisions during generation |
--watch |
Watch for file changes and regenerate automatically |
Examples:
api:lint - Lint Spec Quality
| Option | Description |
|---|---|
--file= |
Path to an existing OpenAPI JSON file to lint |
--domain= |
Generate and lint a specific domain |
--json |
Output results as JSON |
Reports coverage (summaries, descriptions, examples, error responses, request/response bodies), issues (errors, warnings), and a quality score (0-100) with a letter grade.
api:diff - Detect Breaking Changes
| Option | Description |
|---|---|
--fail-on-breaking |
Exit with code 1 if breaking changes are found |
--json |
Output results as JSON |
Compares two OpenAPI specs and reports breaking vs non-breaking changes. Detects removed endpoints, removed response fields, type changes, new required parameters, and added auth requirements.
api:types - Generate TypeScript Definitions
| Option | Description |
|---|---|
--output= |
Output file path (default: resources/js/types/api.d.ts) |
--file= |
Path to an existing OpenAPI JSON file |
--stdout |
Print to stdout instead of writing to file |
Generates TypeScript interfaces from your OpenAPI component schemas, including request/response types for operations that have an operationId.
api:clear-cache - Clear Caches
| Option | Description |
|---|---|
--ast |
Clear AST analysis cache only |
--captures |
Clear captured responses only |
Without flags, clears both AST and capture caches.
api:plugins - List Registered Plugins
Shows all registered plugins with their names, priorities, and capabilities (which interfaces they implement).
Runtime Capture
Runtime capture records real HTTP request/response data during your test runs. This data is then merged with static analysis during generation.
How It Works
- The
CaptureApiResponseMiddlewareintercepts API responses inlocal/testingenvironments (never in production) - For each response, it infers an OpenAPI schema from the JSON structure and stores it to
.schemas/responses/ - Captures are idempotent - if the schema structure hasn't changed between test runs, the file is not rewritten (no noisy git diffs)
- Sensitive data (passwords, tokens, API keys, credit card numbers) is automatically redacted
- During
api:generate, the captured schemas are merged with static analysis results
Configuration
In config/api-documentation.php:
Merge Priority
Control whether static analysis or captured data takes precedence:
static_first(default): Attributes > Static Analysis > Runtime Capturecaptured_first: Attributes > Runtime Capture > Static Analysis
Version Control
Consider committing .schemas/responses/ to version control. Captures are idempotent, so unchanged schemas produce no git diffs. This gives you:
- Documentation that works without running the full test suite
- A record of your API's response shapes over time
- Faster CI builds (skip test run, generate from committed captures)
PHP Attributes
Attributes give you precise control when auto-detection needs help. They always take the highest priority.
#[Tag]
Groups operations in the generated documentation. Applied at class or method level. Optionally includes a description (supports Markdown) that appears in ReDoc/Scalar as introductory content for the tag section.
| Parameter | Type | Default | Description |
|---|---|---|---|
value |
string\|array\|null |
null |
Tag name or array of tag names |
description |
string\|null |
null |
Tag description (Markdown supported). Can also be set via config. |
Precedence: Config
tagsdescriptions override#[Tag]attribute descriptions. See Tags & Documentation.
#[Summary] and #[Description]
Set the operation summary (short) and description (detailed). Also inferred from PHPDoc if not provided.
#[DataResponse]
Define response schemas explicitly. Repeatable for multiple status codes.
| Parameter | Type | Default | Description |
|---|---|---|---|
status |
int |
(required) | HTTP status code |
description |
string |
'' |
Response description |
resource |
string\|array\|null |
[] |
Resource class, Spatie Data class, or inline schema |
headers |
array |
[] |
Response headers (['X-Token' => 'description']) |
isCollection |
bool |
false |
Whether the response is a collection |
#[Parameter]
Enhance request body or response properties. Applied at class level (resources) or method level (form requests). Repeatable.
| Parameter | Type | Default | Description |
|---|---|---|---|
name |
string |
(required) | Property name |
required |
bool |
false |
Whether the property is required |
type |
string |
'string' |
OpenAPI type (also accepts aliases: date, email, uuid, etc.) |
format |
string\|null |
null |
OpenAPI format |
description |
string |
'' |
Property description |
deprecated |
bool |
false |
Mark as deprecated |
example |
mixed |
null |
Example value |
nullable |
bool |
false |
Allow null values |
minLength |
int\|null |
null |
Minimum string length |
maxLength |
int\|null |
null |
Maximum string length |
items |
string\|null |
null |
Array item type |
resource |
string\|null |
null |
Nested resource class |
Type aliases are automatically normalized to valid OpenAPI types:
| Alias | Becomes |
|---|---|
date |
type: "string", format: "date" |
datetime, date-time, timestamp |
type: "string", format: "date-time" |
time |
type: "string", format: "time" |
email |
type: "string", format: "email" |
url, uri |
type: "string", format: "uri" |
uuid |
type: "string", format: "uuid" |
ip, ipv4 |
type: "string", format: "ipv4" |
ipv6 |
type: "string", format: "ipv6" |
binary |
type: "string", format: "binary" |
byte |
type: "string", format: "byte" |
password |
type: "string", format: "password" |
int |
type: "integer" |
bool |
type: "boolean" |
float, double |
type: "number" |
#[PathParameter]
Document path parameters. Repeatable.
| Parameter | Type | Default | Description |
|---|---|---|---|
name |
string |
(required) | Parameter name (must match route parameter) |
type |
string |
'string' |
Parameter type |
format |
string\|null |
null |
Parameter format |
description |
string |
'' |
Parameter description |
required |
bool |
true |
Whether required |
example |
mixed |
null |
Example value |
#[QueryParameter]
Document query parameters explicitly. Repeatable.
| Parameter | Type | Default | Description |
|---|---|---|---|
name |
string |
(required) | Parameter name |
type |
string |
'string' |
Parameter type |
format |
string\|null |
null |
Parameter format |
description |
string |
'' |
Parameter description |
required |
bool |
false |
Whether required |
example |
mixed |
null |
Example value |
enum |
array\|null |
null |
Allowed values |
#[ResponseHeader]
Document response headers. Repeatable.
#[RequestBody] and #[ResponseBody]
Low-level control over request/response schemas when you need full override.
#[ExcludeFromDocs]
Exclude a controller or specific method from documentation.
#[AdditionalDocumentation]
Link to external documentation.
#[DocumentationFile]
Route an endpoint to a specific documentation file (for multi-file setups).
#[IgnoreDataParameter]
Exclude a Spatie Data property from the request body schema.
PHPDoc Annotations
The package also reads PHPDoc blocks:
- The first line becomes the
summary, the rest becomes thedescription @queryParamentries are extracted as query parameters@returntype is used for response schema detection@deprecatedmarks the operation as deprecated
Configuration
After publishing the config (php artisan vendor:publish --tag="api-documentation-config"), the file is at config/api-documentation.php. Key sections:
OpenAPI Metadata
Route Filtering
Servers
Analysis
Code Samples
When enabled, adds x-codeSamples to each operation with working cURL, fetch, Guzzle, and requests examples.
Error Responses
Validation Rule Mappings
Tags & Documentation
Enrich your documentation viewers (ReDoc, Scalar) with tag descriptions, navigation groups, documentation-only pages, and external links. All settings are zero-config by default — empty arrays and null values produce no output.
Tag Descriptions
Add Markdown descriptions to tags. These appear as introductory content in tag sections.
Descriptions can also be set via the #[Tag] attribute:
Config descriptions take precedence over attribute descriptions.
Tag Groups (x-tagGroups)
Group tags into sections for the ReDoc/Scalar navigation sidebar:
This emits the x-tagGroups vendor extension recognized by ReDoc and Scalar. By default, any tags not assigned to a group are automatically collected into an "Other" group so they remain visible in the sidebar. To instead hide ungrouped tags (the default ReDoc/Scalar behavior), set:
Trait Tags (x-traitTag)
Add documentation-only tags that appear in the sidebar but aren't associated with any operations. Useful for guides, introductions, or changelogs:
Trait tags are emitted with x-traitTag: true and support full Markdown in the description.
External Documentation
Add a spec-level link to external documentation:
Set to null (default) to omit from the spec.
Domain Overrides
All four settings (tags, tag_groups, trait_tags, external_docs) can be overridden per domain:
Multi-Domain Support
Generate separate specs for different API domains:
Multi-File Support
Output multiple documentation files from a single app:
Use #[DocumentationFile('internal')] on controllers to route them to a specific file.
Documentation Viewers
Three built-in documentation UIs are available. Enable them in your config:
When any UI is enabled, a default hub page is registered at /documentation that redirects to your chosen default viewer.
To publish and customize the view templates:
Output Formats
JSON (default)
YAML
Requires the ext-yaml PHP extension, or falls back to a built-in converter.
Postman Collection
Exports a Postman Collection v2.1 file, grouped by tags, with auth headers, path/query parameters, and request body examples.
TypeScript Definitions
Plugin System
The package is built around 6 plugin interfaces. Each interface represents a specific analysis capability. All built-in analyzers use the same interfaces, so plugins have the same power as core functionality.
Plugin Interfaces
| Interface | Purpose | Method Signature |
|---|---|---|
RequestBodyExtractor |
Extract request body schemas | extract(AnalysisContext $ctx): ?SchemaResult |
ResponseExtractor |
Extract response schemas | extract(AnalysisContext $ctx): array (of ResponseResult) |
QueryParameterExtractor |
Extract query parameters | extract(AnalysisContext $ctx): array (of ParameterResult) |
SecuritySchemeDetector |
Detect auth schemes | detect(AnalysisContext $ctx): ?array |
OperationTransformer |
Post-process operations | transform(array $operation, AnalysisContext $ctx): array |
ExceptionSchemaProvider |
Custom exception schemas | provides(string $exceptionClass): bool + getResponse(string $exceptionClass): ResponseResult |
Every plugin must implement the base Plugin interface:
Priority System
Analyzers run in priority order (highest first). The first non-null result wins for request bodies; all results are collected for responses and query parameters.
| Range | Used By |
|---|---|
| 100 | Attribute-based analyzers (manual overrides) |
| 80-90 | Core static analyzers (FormRequest, ReturnType) |
| 60-70 | Runtime capture analyzers |
| 40-50 | Built-in plugins (BearerAuth, Pagination, Spatie) |
| 1-39 | Community plugins (recommended range) |
Registering Plugins
Via config:
Via Composer auto-discovery (for package authors):
Programmatically at runtime:
Built-in Plugins
BearerAuthPlugin
Always active. Detects Bearer token authentication from auth:sanctum, auth:api, and jwt.auth middleware. Extracts OAuth scopes and Sanctum abilities.
PaginationPlugin
Always active. Detects paginate(), simplePaginate(), and cursorPaginate() calls via AST analysis. Wraps response schemas with data/meta/links pagination envelope.
CodeSamplePlugin
Enabled when code_samples.enabled is true in config. Generates working code examples in bash (cURL), JavaScript (fetch), PHP (Guzzle), and Python (requests) with proper auth headers and request bodies.
SpatieDataPlugin
Auto-detected when spatie/laravel-data is installed. Extracts request body schemas from Spatie Data DTO constructor properties. Handles optional properties, Lazy types, and nested DTOs with $ref deduplication.
SpatieQueryBuilderPlugin
Auto-detected when spatie/laravel-query-builder is installed. Extracts filter[...], sort, include, and fields query parameters from allowedFilters(), allowedSorts(), allowedIncludes(), and allowedFields() calls.
JsonApiPlugin
Auto-detected when timacdonald/json-api is installed. Generates proper JSON:API response schemas (data/attributes/relationships/links), sets content type to application/vnd.api+json, and adds the Accept header.
LaravelActionsPlugin
Auto-detected when lorisleiva/laravel-actions is installed. Extracts request schemas from Action classes using the AsController trait by analyzing rules() methods and handle() parameters.
Creating a Plugin
Here is a complete example of a plugin that adds a custom header to every operation:
Register it:
Plugin with Multiple Capabilities
A plugin can implement multiple interfaces:
The AnalysisContext Object
Every analyzer receives an AnalysisContext that provides:
$ctx->routeInfo- Route metadata (URI, methods, middleware, parameters)$ctx->reflectionMethod- PHPReflectionMethodof the controller action$ctx->reflectionClass- PHPReflectionClassof the controller$ctx->ast- Parsed AST statements of the controller method body$ctx->classAttributes- PHP 8 attributes on the controller class$ctx->methodAttributes- PHP 8 attributes on the method
Plugin Safety
Plugins that throw during boot() are automatically unregistered and logged. A failing plugin never breaks documentation generation for other routes.
Community Plugin Ideas
Below are detailed implementation examples for plugins the community could build. Each example is a complete, working plugin that can be copied into your project and customized.
API Key Authentication
Detects custom middleware that validates API keys via headers or query parameters.
RFC 7807 Problem Details
Maps exceptions to standardized Problem Details responses. This is the only interface (ExceptionSchemaProvider) with no built-in implementation — a great opportunity for a community package.
League Fractal Transformers
Detects Fractal transformers and extracts response schemas by analyzing the transform() method's return array via AST parsing.
Versioning Headers
Detects API versioning strategies and documents the version parameter on each operation.
Register with custom configuration:
Cache Control Headers
Detects caching middleware and documents conditional request headers (ETag, If-None-Match).
Integrations
Spatie Laravel Data
When spatie/laravel-data is installed, Data objects used as controller method parameters are automatically documented:
Spatie Laravel Query Builder
When spatie/laravel-query-builder is installed, allowed filters, sorts, and includes are extracted as query parameters:
Laravel Actions
When lorisleiva/laravel-actions is installed, Action classes with the AsController trait are analyzed:
JSON:API (timacdonald/json-api)
When timacdonald/json-api is installed, JSON:API resources produce proper data/attributes/relationships response schemas.
CI/CD Integration
Generate on Deploy
Block Breaking Changes
Validate Spec Quality
Generate with Captures in CI
Security
The package is designed with security as a priority:
- Production safe: The capture middleware is gated behind environment checks and will never run in production, even if
DOC_CAPTURE_MODEis accidentally set - Sensitive data redaction: Passwords, tokens, API keys, credit card numbers, and SSNs are automatically redacted in captured examples
- No runtime overhead: The package only runs during documentation generation (
api:generate) and optionally during testing (capture mode). It adds zero overhead to production request handling
Please review our security policy on how to report security vulnerabilities.
Credits
- Jakob Bennemann
- All Contributors
License
The MIT License (MIT). Please see License File for more information.
All versions of laravel-api-documentation with dependencies
illuminate/contracts Version ^10.0 || ^11.0 || ^12.0
nikic/php-parser Version ^5.3
phpstan/phpdoc-parser Version ^2.0
php-openapi/openapi Version ^2.0
spatie/laravel-package-tools Version ^1.16