spatie/laravel-route-attributes
Register Laravel routes using PHP 8 attributes on controller methods (Get/Post/etc.). Automatically scans configured controller directories and registers routes without manual Route:: definitions. Includes config publishing and optional enabling/disabling of auto registration.
Installation:
composer require spatie/laravel-route-attributes
Publish the config (optional):
php artisan vendor:publish --provider="Spatie\RouteAttributes\RouteAttributesServiceProvider"
First Use Case:
Replace a basic routes/web.php route:
// Before: routes/web.php
Route::get('/dashboard', [DashboardController::class, 'index']);
// After: DashboardController.php
use Spatie\RouteAttributes\Attributes\Get;
class DashboardController {
#[Get('/dashboard')]
public function index() { ... }
}
Where to Look First:
config/route-attributes.php for customization options (e.g., namespace scanning).php artisan route:list to verify auto-registered routes.Attribute-Based Routing:
Route::get(), Route::post(), etc., with attributes:
#[Get('/users/{id}', name: 'users.show')]
public function show(User $user) { ... }
Get, Post, Put, Delete, Patch, Options, Head).Middleware Integration:
#[Get('/admin', middleware: ['auth', 'admin'])]
public function adminDashboard() { ... }
Route Grouping:
RouteAttributesGroup for shared prefixes/middleware:
use Spatie\RouteAttributes\Attributes\RouteAttributesGroup;
#[RouteAttributesGroup(prefix: 'api/v1', middleware: ['api'])]
class ApiV1Controller {
#[Get('/users')]
public function index() { ... }
}
Dynamic Route Parameters:
#[Get('/posts/{post}')]
public function show(Post $post) { ... }
Route Caching:
php artisan route:cache (works seamlessly with attributes).scanned_namespaces in config/route-attributes.php to auto-discover controllers.spatie/laravel-api-resource for attribute-driven API responses.Route::getRoutes()->getByName() to assert routes in tests:
$this->assertTrue(Route::getRoutes()->getByName('users.show')->count() > 0);
Namespace Scanning:
scanned_namespaces means routes won’t auto-register.php artisan route:clear and check logs for missing routes.Route Overrides:
Route::get() calls in web.php take precedence over attributes.#[Route(name: 'unique.name')] to avoid conflicts.Middleware Conflicts:
web) may clash with attribute-defined middleware.middleware: ['except' => ['web']] to exclude global middleware.Caching Issues:
php artisan route:clear
Route Not Found?:
scanned_namespaces.#[Get] vs #[GET]).php artisan route:list to inspect registered routes.Attribute Not Recognized:
config/app.php.Custom Attributes:
#[Attribute]
class CustomRoute extends Get {
public function __construct(string $uri, array $options = []) {
parent::__construct($uri, $options + ['custom' => true]);
}
}
Route Filtering:
RouteAttributesServiceProvider events to filter routes before registration:
RouteAttributesServiceProvider::macro('registeringRoutes', function ($routes) {
$routes->reject(fn ($route) => str_contains($route->uri(), 'disabled'));
});
Dynamic URI Generation:
name option):
route('users.show', ['id' => 1]);
scanned_namespaces to reduce scanning overhead.ROUTE_CACHING=true in .env) for faster route resolution.How can I help you explore Laravel packages today?