spatie/laravel-route-attributes

repository·main·Indexed 21 days ago

https://github.com/spatie/laravel-route-attributes

A Laravel package that allows registering routes using PHP 8 attributes directly on controller methods. It provides attributes for standard HTTP verbs (Get, Post, Put, Patch, Delete, Options, Any), resource and API resource controllers, and structural organization via Prefix, Domain, and Group attributes. It also supports route parameter constraints with Where attributes, default values via Defaults, and route model binding configurations like ScopeBindings and WithTrashed.

Tokens
5.1K
Snippets
19
Records
22
Agent score
74%

What's inside spatie/laravel-route-attributes

  1. Register routes using PHP 8 attributes

    main

    Instead of defining routes in routes/web.php or routes/api.php, you can use PHP 8 attributes directly on controller methods. This automatically registers the route in Laravel.

    Example of a GET route:

    use Spatie\RouteAttributes\Attributes\Get;
    
    class MyController
    {
        #[Get('my-route')]
        public function myMethod()
        {
        }
    }

    This is equivalent to: Route::get('my-route', [MyController::class, 'myMethod']);

  2. Install spatie/laravel-route-attributes

    main

    Install the package via Composer and publish the configuration file to customize how routes are discovered and registered.

    composer require spatie/laravel-route-attributes
    
    php artisan vendor:publish --provider="Spatie\RouteAttributes\RouteAttributesServiceProvider" --tag="config"
  3. Configure route attribute registration

    main

    The configuration file allows you to enable/disable automatic registration, define which directories to scan for attributes, and apply group settings (like middleware or prefixes) to specific directories.

    Key configuration options:

    • enabled: Boolean to turn automatic registration on or off.
    • directories: An array of directories to scan. You can provide a simple path string or an associative array to apply group configuration to that path.
    • patterns: An array of glob patterns to include specific files (e.g., *Controller.php).
    • not_patterns: An array of glob patterns to exclude specific files (e.g., *Test.php).

    For directories outside the application root, use a namespace => path pattern or a path => ['namespace' => '...'] pattern.

    return [
        'enabled' => true,
    
        'directories' => [
            app_path('Http/Controllers'),
    
            // Apply group configuration to a directory
            app_path('Http/Controllers/Web') => [
                'middleware' => ['web']
            ],
    
            // Using namespace/path mapping for external modules
            'Modules\Admin\Http\Controllers\' => base_path('admin-module/Http/Controllers'),
    
            // Using patterns to filter files
            base_path('app-modules/Blog') => [
                'patterns' => ['*Controller.php'],
                'not_patterns' => ['*Test.php'],
            ],
        ],
    ];
  4. Configure class-level route attributes

    main

    You can use several PHP 8 attributes on your controller classes to define shared route properties. This reduces repetition in your route files by applying settings to all methods within the class.

    Available class-level attributes include:

    • Prefix: Sets a URL prefix for all routes in the class.
    • Domain: Sets a specific domain for the routes.
    • DomainFromConfig: Sets the domain by pulling a value from a Laravel configuration key.
    • Group: Allows grouping routes with specific domain, prefix, where constraints, or an as name.
    • Middleware: Applies middleware to all routes in the class.
    • Resource: Configures resource controller behavior (see Resource Controller Attributes).
    • Where: Defines parameter constraints (e.g., regex) for routes in the class.
    • Defaults: Sets default values for route parameters.
    • ScopeBindings: Controls whether Laravel's implicit route model binding scope is applied.
    • WithTrashed: Enables support for soft-deleted models in route bindings.
  5. Configure Resource Controller Attributes

    main

    When using the Resource attribute on a class, you can fine-tune how the resource routes are generated using the following properties:

    • resource: The name of the resource.
    • apiResource: If true, generates API-specific resource routes.
    • parameters: Customizes the parameter names used in the routes.
    • shallow: If true, creates shallow resource routing.
    • only: Limits the routes to a specific subset of actions (string or array).
    • except: Excludes specific actions from the resource routes (string or array).
    • names: Customizes the route names (string or array).
  6. Set route parameter defaults

    main

    Use the #[Defaults] attribute to define default values for optional route parameters. This can be applied at the class level (to set a default for all methods) or the method level (to override or add specific defaults).

    use Spatie\\RouteAttributes\\Attributes\\Defaults;
    use Spatie\\RouteAttributes\\Attributes\\Get;
    
    class MyController
    {
        #[Defaults('param', 'default-value')]
        #[Get('route/{param?}')]
        public function index($param) {}
    }
  7. Register basic HTTP verb routes

    main

    You can register standard HTTP routes by applying specific verb attributes to controller methods. Each attribute accepts the URI as its first argument.

    Available verb attributes:

    • #[Get('uri')]
    • #[Post('uri')]
    • #[Put('uri')]
    • #[Patch('uri')]
    • #[Delete('uri')]
    • #[Options('uri')]
    • #[Any('uri')] (registers the route for all HTTP verbs)
    • #[Route(['verb1', 'verb2'], 'uri')] (registers the route for a specific set of verbs)
    use Spatie\
    outeAttributes\\Attributes\\Get;
    
    class MyController
    {
        #[Get('my-route')]
        public function myMethod()
        {
        }
    }
  8. Apply prefixes, domains, and groups to routes

    main

    You can organize routes by applying structural attributes to controller classes:

    • #[Prefix('prefix-value')]: Prefixes all routes in the class.
    • #[Domain('domain.com')]: Sets the domain for all routes in the class.
    • #[DomainFromConfig('config.key')]: Sets the domain using a value retrieved from your Laravel configuration.
    • #[Group(domain: '...', prefix: '...')]: Allows defining multiple groups within a single class. Each Group attribute creates a new set of routes with the specified domain and prefix.
    use Spatie\\RouteAttributes\\Attributes\\Group;
    use Spatie\\RouteAttributes\\Attributes\\Get;
    
    #[Group(domain: 'sub.example.com', prefix: 'api')]
    #[Group(domain: 'other.example.com', prefix: 'v2')]
    class MyController
    {
        #[Get('route-one')] // Registered as sub.example.com/api/route-one
        public function methodOne() {}
    
        #[Get('route-two')] // Registered as other.example.com/v2/route-two
        public function methodTwo() {}
    }
  9. Enable scoped bindings and WithTrashed support

    main

    Scoped Bindings

    To ensure nested Eloquent models are scoped to their parents (e.g., /users/{user}/posts/{post}), use the #[ScopeBindings] attribute. You can disable this by passing false: #[ScopeBindings(false)].

    WithTrashed

    To allow route model binding to include soft-deleted models, use the #[WithTrashed] attribute. You can disable this for specific methods using #[WithTrashed(false)].

    use Spatie\\RouteAttributes\\Attributes\\Get;
    use Spatie\\RouteAttributes\\Attributes\\ScopeBindings;
    use Spatie\\RouteAttributes\\Attributes\\WithTrashed;
    
    class MyController
    {
        #[Get('users/{user}/posts/{post}')]
        #[ScopeBindings]
        #[WithTrashed]
        public function show(User $user, Post $post) {}
    }
  10. Configure route names and middleware

    main

    All HTTP verb attributes (Get, Post, etc.) support the following optional parameters:

    • name: A string representing the route name.
    • middleware: A middleware class or an array of middleware classes.

    You can also apply middleware to an entire controller class using the #[Middleware] attribute. Method-level middleware will be merged with class-level middleware.

    use Spatie\\RouteAttributes\\Attributes\\Get;
    use Spatie\\RouteAttributes\\Attributes\\Middleware;
    
    #[Middleware(MyMiddleware::class)]
    class MyController
    {
        #[Get('my-route', name: "my-route-name", middleware: MyOtherMiddleware::class)]
        public function myMethod()
        {
        }
    }
  11. Constrain route parameters with Where attributes

    main

    Use the Where attribute to apply regular expression constraints to route parameters. This can be applied to a class (for all methods) or a specific method.

    Helper Attributes

    For common patterns, use these shorthand attributes:

    • #[WhereAlpha('name')]
    • #[WhereAlphaNumeric('name')]
    • #[WhereIn('name', ['val1', 'val2'])]
    • #[WhereNumber('name')]
    • #[WhereUlid('name')]
    • #[WhereUuid('name')]
    use Spatie\\RouteAttributes\\Attributes\\Get;
    use Spatie\\RouteAttributes\\Attributes\\Where;
    use Spatie\\RouteAttributes\\Attributes\\WhereAlphaNumeric;
    
    class MyController
    {
        #[Where('id', '[0-9]+')]
        #[Get('user/{id}')]
        public function showUser($id) {}
    
        #[WhereAlphaNumeric('slug')]
        #[Get('post/{slug}')]
        public function showPost($slug) {}
    }