wadakatu / laravel-spectrum
Zero-annotation API documentation generator for Laravel and Lumen
Requires
- php: ^8.1
- illuminate/console: ^10.0|^11.0|^12.0
- illuminate/routing: ^10.0|^11.0|^12.0
- illuminate/support: ^10.0|^11.0|^12.0
- nikic/php-parser: ^5.5
- symfony/finder: ^6.0|^7.0
- workerman/workerman: ^4.1|^5.0
Requires (Dev)
- laravel/pint: ^1.23
- orchestra/testbench: ^8.0|^9.0|^10.0
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^10.0|^11.0
- dev-main
- v0.0.4-alpha
- v0.0.3-alpha
- v0.0.2-alpha
- v0.0.1-alpha
- dev-fix/swagger-ui-standalone-layout
- dev-update-banner-1751966829
- dev-fix/workerman-startup-args
- dev-update-banner-1751962486
- dev-feat/improve-openapi-tag-generation
- dev-fix/openapi-parameter-schema-format
- dev-fix/project_name
- dev-update-banner-1751957497
- dev-fix/banner-version-regex
- dev-fix/schema-generator-example-key
This package is auto-updated.
Last update: 2025-07-08 09:59:22 UTC
README
🎯 Zero-annotation API documentation generator for Laravel & Lumen
Transform your existing Laravel/Lumen APIs into comprehensive OpenAPI documentation without writing a single annotation or modifying your code.
✨ Key Features
📸 Demo
# Generate your API documentation instantly php artisan spectrum:generate # Watch mode for real-time updates php artisan spectrum:watch
🔧 Requirements
- PHP 8.1 or higher
- Laravel 10.x, 11.x, or 12.x / Lumen 10.x, 11.x, 12.x
- Composer 2.0 or higher
📦 Installation
composer require wadakatu/laravel-spectrum --dev
That's it! No configuration needed to get started.
🚀 Quick Start
1. Generate Documentation
# Generate OpenAPI documentation php artisan spectrum:generate # Generate in YAML format php artisan spectrum:generate --format=yaml # Custom output path php artisan spectrum:generate --output=public/api-docs.json
2. Real-time Preview (Development)
# Start the watcher with live reload php artisan spectrum:watch # Visit http://localhost:8080 to see your documentation
3. View with Swagger UI
<!-- Add to your blade template --> <div id="swagger-ui"></div> <script src="https://unpkg.com/swagger-ui-dist/swagger-ui-bundle.js"></script> <script> SwaggerUIBundle({ url: "/api-documentation.json", dom_id: '#swagger-ui', }) </script>
📖 Usage Examples
Laravel FormRequest Example
// app/Http/Requests/StoreUserRequest.php class StoreUserRequest extends FormRequest { public function rules() { return [ 'name' => 'required|string|max:255', 'email' => 'required|email|unique:users', 'password' => 'required|string|min:8|confirmed', 'age' => 'nullable|integer|min:18|max:120', 'roles' => 'array', 'roles.*' => 'exists:roles,id', ]; } public function messages() { return [ 'email.unique' => 'This email is already registered.', ]; } } // Controller - automatically documented! public function store(StoreUserRequest $request) { $user = User::create($request->validated()); return new UserResource($user); }
Laravel API Resource Example
// app/Http/Resources/UserResource.php class UserResource extends JsonResource { public function toArray($request) { return [ 'id' => $this->id, 'name' => $this->name, 'email' => $this->email, 'email_verified' => $this->email_verified_at !== null, 'roles' => RoleResource::collection($this->whenLoaded('roles')), 'created_at' => $this->created_at->toDateTimeString(), 'profile' => new ProfileResource($this->whenLoaded('profile')), ]; } }
Fractal Transformer Example
// app/Transformers/UserTransformer.php class UserTransformer extends TransformerAbstract { protected $availableIncludes = ['posts', 'profile', 'followers']; protected $defaultIncludes = ['profile']; public function transform(User $user) { return [ 'id' => (int) $user->id, 'name' => $user->name, 'email' => $user->email, 'member_since' => $user->created_at->toDateString(), 'is_active' => (bool) $user->is_active, ]; } public function includePosts(User $user) { return $this->collection($user->posts, new PostTransformer()); } }
Lumen Inline Validation Example
// Lumen Controller with inline validation public function store(Request $request) { // Automatically detected and documented! $this->validate($request, [ 'title' => 'required|string|max:255', 'content' => 'required|string', 'status' => 'required|in:draft,published', 'tags' => 'array', 'tags.*' => 'string|max:50', ]); $post = Post::create($request->all()); return $this->fractal->item($post, new PostTransformer()); }
Authentication Configuration
// Automatically detects authentication methods Route::middleware('auth:sanctum')->group(function () { Route::apiResource('users', UserController::class); }); // API Key authentication Route::middleware('auth.apikey')->group(function () { Route::get('/stats', StatsController::class); });
⚙️ Configuration
Publish the configuration file for advanced customization:
php artisan vendor:publish --tag=spectrum-config
Configuration Options
// config/spectrum.php return [ // API Information 'title' => env('APP_NAME', 'Laravel API'), 'version' => '1.0.0', 'description' => 'API Documentation', // Server Configuration 'servers' => [ [ 'url' => env('APP_URL'), 'description' => 'Production server', ], ], // Route Detection 'route_patterns' => [ 'api/*', // Include all /api routes 'api/v1/*', // Version-specific routes 'api/v2/*', ], 'excluded_routes' => [ 'api/health', // Exclude health checks 'api/debug/*', // Exclude debug endpoints ], // Response Formats 'response_formats' => [ 'resource' => true, // Laravel Resources 'fractal' => true, // Fractal Transformers 'json' => true, // Plain JSON responses ], // Security Schemes 'security_schemes' => [ 'bearer' => [ 'type' => 'http', 'scheme' => 'bearer', 'bearerFormat' => 'JWT', ], 'apiKey' => [ 'type' => 'apiKey', 'in' => 'header', 'name' => 'X-API-Key', ], ], // Tag Mappings for Organizing Endpoints 'tags' => [ // Exact match 'api/v1/auth/login' => 'Authentication', 'api/v1/auth/logout' => 'Authentication', // Wildcard patterns 'api/v1/auth/*' => 'Authentication', 'api/v1/admin/*' => 'Administration', 'api/v1/billing/*' => 'Billing', 'api/v1/users/*' => 'User Management', ], // Cache Configuration 'cache' => [ 'enabled' => env('SPECTRUM_CACHE_ENABLED', true), 'ttl' => 3600, // 1 hour ], // Watch Mode Settings 'watch' => [ 'port' => 8080, 'host' => '127.0.0.1', 'open_browser' => true, ], ];
🎯 Advanced Features
Custom Type Mappings
// config/spectrum.php 'type_mappings' => [ 'json' => ['type' => 'object'], 'uuid' => ['type' => 'string', 'format' => 'uuid'], 'decimal' => ['type' => 'number', 'format' => 'float'], ],
Automatic Tag Generation
Laravel Spectrum automatically generates tags for your API endpoints to keep them organized:
- Automatic extraction: Tags are extracted from URL paths (e.g.,
/api/posts/{post}
→Post
) - Multi-level support: Nested resources generate multiple tags (e.g.,
/api/posts/{post}/comments
→['Post', 'Comment']
) - Parameter removal: Route parameters like
{post}
are automatically cleaned up - Controller fallback: When URLs are generic, the controller name is used as a fallback
- Custom mappings: Override automatic tags using configuration
// config/spectrum.php 'tags' => [ // Group all authentication endpoints 'api/v1/auth/*' => 'Authentication', // Specific endpoint mapping 'api/v1/users/profile' => 'User Profile', // Multiple endpoints to same tag 'api/v1/orders/*' => 'Orders', 'api/v1/invoices/*' => 'Billing', 'api/v1/payments/*' => 'Billing', ],
Response Examples
// Automatically generates examples from your Resources class ProductResource extends JsonResource { public function toArray($request) { return [ 'id' => $this->id, 'name' => $this->name, 'price' => $this->price, 'currency' => 'USD', 'in_stock' => $this->quantity > 0, 'meta' => [ 'sku' => $this->sku, 'weight' => $this->weight, ], ]; } }
Error Response Customization
// Automatic 422 validation error format { "message": "The given data was invalid.", "errors": { "email": [ "The email field is required.", "The email must be a valid email address." ] } } // Custom error responses class Handler extends ExceptionHandler { public function render($request, Throwable $exception) { if ($exception instanceof ModelNotFoundException) { return response()->json([ 'error' => 'Resource not found', 'code' => 'RESOURCE_NOT_FOUND' ], 404); } return parent::render($request, $exception); } }
🔧 Troubleshooting
Common Issues
Q: Documentation is not generating for some routes
# Check registered routes php artisan route:list --path=api # Clear cache php artisan spectrum:clear-cache
Q: FormRequest validation rules not detected
# Ensure FormRequest is properly type-hinted public function store(StoreUserRequest $request) // ✅ Correct public function store(Request $request) // ❌ Won't detect custom rules
Q: Fractal includes not appearing
# Define available includes in transformer protected $availableIncludes = ['posts', 'profile']; // ✅ Will be documented
🤝 Contributing
We welcome contributions! Please see our Contributing Guide for details.
# Setup development environment git clone https://github.com/wadakatu/laravel-spectrum.git cd laravel-spectrum composer install # Run tests composer test # Run static analysis composer analyze # Fix code style composer format:fix
📄 License
The MIT License (MIT). Please see License File for more information.
Made with ❤️ by Wadakatu
Star ⭐ this repo if you find it helpful!