Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Use PHP 8 attributes to register routes in a Laravel app

License

NotificationsYou must be signed in to change notification settings

matchory/laravel-route-attributes

 
 

Repository files navigation

Latest Version on PackagistTestsType CoverageTotal Downloads

This package provides attributes to automatically register routes. Here's a quick example:

useSpatie\RouteAttributes\Attributes\Get;class MyController{    #[Get('my-route')]publicfunctionmyMethod()    {    }}

This attribute will automatically register this route:

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

Are you a visual learner?

In this video you'll get an introduction to PHP 8 attributes and how this laravel-routes-attributes works under the hood.

Support us

We invest a lot of resources into creatingbest in class open source packages. You can support us bybuying one of our paid products.

We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address onour contact page. We publish all received postcards onour virtual postcard wall.

Installation

You can install the package via composer:

composer require spatie/laravel-route-attributes

You can publish the config file with:

php artisan vendor:publish --provider="Spatie\RouteAttributes\RouteAttributesServiceProvider" --tag="config"

This is the contents of the published config file:

return [/*     *  Automatic registration of routes will only happen if this setting is `true`     */'enabled' =>true,/*     * Controllers in these directories that have routing attributes     * will automatically be registered.     *     * Optionally, you can specify group configuration by using key/values     */'directories' => [app_path('Http/Controllers'),app_path('Http/Controllers/Web') => ['middleware' => ['web']        ],app_path('Http/Controllers/Api') => ['prefix' =>'api','middleware' =>'api'        ],    ],];

For controllers outside the applications root namespace directories can also be added using anamespace => path pattern in the directories array. In the following example controllers fromModules\Admin\Http\Controllers will be included.

'directories' => ['Modules\Admin\Http\Controllers\\' =>base_path('admin-module/Http/Controllers'),// Orbase_path('admin-module/Http/Controllers') => ['namespace' =>'Modules\Admin\Http\Controllers\\'    ],app_path('Http/Controllers'),],

If you are using a directory structure where you co-locate multiple types of files in the same directory and want tobe more specific about which files are checked for route attributes, you can use thepatterns andnot_patternsoptions. For example, if you are co-locating your tests with your controllers you could use thepatterns option to onlylook in controller files, or you could usenot_patterns to configure it to not look in test files for routeattributes.

'directories' => [base_path('app-modules/Blog') => [// only register routes in files that match the patterns'patterns' => ['*Controller.php'],// do not register routes in files that match the patterns'not_patterns' => ['*Test.php'],    ],],

Usage

The package provides several annotations that should be put on controller classes and methods. These annotations will be used to automatically register routes

Adding a GET route

useSpatie\RouteAttributes\Attributes\Get;class MyController{    #[Get('my-route')]publicfunctionmyMethod()    {    }}

This attribute will automatically register this route:

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

Using other HTTP verbs

We have left no HTTP verb behind. You can use these attributes on controller methods.

#[Spatie\RouteAttributes\Attributes\Post('my-uri')]#[Spatie\RouteAttributes\Attributes\Put('my-uri')]#[Spatie\RouteAttributes\Attributes\Patch('my-uri')]#[Spatie\RouteAttributes\Attributes\Delete('my-uri')]#[Spatie\RouteAttributes\Attributes\Options('my-uri')]

Resource controllers

To register aresource controller, use theResource attribute as shown in the example below.

You can useonly orexcept parameters to manage your resource routes availability.

You can useparameters parameter to modify the default parameters set by the resource attribute.

You can use thenames parameter to set the route names for the resource controller actions. Pass a string value to set a base route name for each controller action or pass an array value to define the route name for each controller action.

You can useshallow parameter to make a nested resource to apply nesting only to routes without a unique child identifier (index,create,store).

You can useapiResource boolean parameter to only include actions used in APIs. Alternatively, you can use theApiResource attribute, which extends theResource attribute class, but the parameterapiResource is already set totrue.

UsingResource attribute withDomain,Prefix andMiddleware attributes works as well.

useSpatie\RouteAttributes\Attributes\Resource;#[Prefix('api/v1')]#[Resource(    resource:'photos.comments',    apiResource:true,    shallow:true,    parameters: ['comments' =>'comment:uuid'],    names:'api.v1.photoComments',    except: ['destroy'],)]// OR #[ApiResource(resource: 'photos.comments', shallow: true, ...)]class PhotoCommentController{publicfunctionindex(Photo$photo)    {    }publicfunctionstore(Request$request,Photo$photo)    {    }publicfunctionshow(Comment$comment)    {    }publicfunctionupdate(Request$request,Comment$comment)    {    }}

The attribute in the example above will automatically register following routes:

Route::get('api/v1/photos/{photo}/comments', [PhotoCommentController::class,'index'])->name('api.v1.photoComments.index');Route::post('api/v1/photos/{photo}/comments', [PhotoCommentController::class,'store'])->name('api.v1.photoComments.store');Route::get('api/v1/comments/{comment}', [PhotoCommentController::class,'show'])->name('api.v1.photoComments.show');Route::match(['put','patch'],'api/v1/comments/{comment}', [PhotoCommentController::class,'update'])->name('api.v1.photoComments.update');

Using multiple verbs

To register a route for all verbs, you can use theAny attribute:

#[Spatie\RouteAttributes\Attributes\Any('my-uri')]

To register a route for a few verbs at once, you can use theRoute attribute directly:

#[Spatie\RouteAttributes\Attributes\Route(['put','patch'],'my-uri')]

Specify a route name

All HTTP verb attributes accept a parameter namedname that accepts a route name.

useSpatie\RouteAttributes\Attributes\Get;class MyController{    #[Get('my-route', name:"my-route-name")]publicfunctionmyMethod()    {    }}

This attribute will automatically register this route:

Route::get('my-route', [MyController::class,'myMethod'])->name('my-route-name');

Adding middleware

All HTTP verb attributes accept a parameter namedmiddleware that accepts a middleware class or an array of middleware classes.

useSpatie\RouteAttributes\Attributes\Get;class MyController{    #[Get('my-route', middleware: MyMiddleware::class)]publicfunctionmyMethod()    {    }}

This annotation will automatically register this route:

Route::get('my-route', [MyController::class,'myMethod'])->middleware(MyMiddleware::class);

To apply middleware on all methods of a class you can use theMiddleware attribute. You can mix this with applying attribute on a method.

useSpatie\RouteAttributes\Attributes\Get;useSpatie\RouteAttributes\Attributes\Middleware;#[Middleware(MyMiddleware::class)]class MyController{    #[Get('my-route')]publicfunctionfirstMethod()    {    }    #[Get('my-other-route', middleware: MyOtherMiddleware::class)]publicfunctionsecondMethod()    {    }}

These annotations will automatically register these routes:

Route::get('my-route', [MyController::class,'firstMethod'])->middleware(MyMiddleware::class);Route::get('my-other-route', [MyController::class,'secondMethod'])->middleware([MyMiddleware::class, MyOtherMiddleware::class]);

Specifying a prefix

You can use thePrefix annotation on a class to prefix the routes of all methods of that class.

useSpatie\RouteAttributes\Attributes\Get;useSpatie\RouteAttributes\Attributes\Post;useSpatie\RouteAttributes\Attributes\Prefix;#[Prefix('my-prefix')]class MyController{    #[Get('my-get-route')]publicfunctionmyGetMethod()    {    }    #[Post('my-post-route')]publicfunctionmyPostMethod()    {    }}

These annotations will automatically register these routes:

Route::get('my-prefix/my-get-route', [MyController::class,'myGetMethod']);Route::post('my-prefix/my-post-route', [MyController::class,'myPostMethod']);

Specifying a domain

You can use theDomain annotation on a class to prefix the routes of all methods of that class.

useSpatie\RouteAttributes\Attributes\Get;useSpatie\RouteAttributes\Attributes\Post;useSpatie\RouteAttributes\Attributes\Domain;#[Domain('my-subdomain.localhost')]class MyController{    #[Get('my-get-route')]publicfunctionmyGetMethod()    {    }    #[Post('my-post-route')]publicfunctionmyPostMethod()    {    }}

These annotations will automatically register these routes:

Route::get('my-get-route', [MyController::class,'myGetMethod'])->domain('my-subdomain.localhost');Route::post('my-post-route', [MyController::class,'myPostMethod'])->domain('my-subdomain.localhost');

Specifying a domain from a config key

There maybe a need to define a domain from a configuration file, for example whereyour subdomain will be different on your development environment to your production environment.

// config/domains.phpreturn ['main' =>env('SITE_URL','example.com'),'subdomain' =>env('SUBDOMAIN_URL','subdomain.example.com')];
useSpatie\RouteAttributes\Attributes\Get;useSpatie\RouteAttributes\Attributes\Post;useSpatie\RouteAttributes\Attributes\DomainFromConfig;#[DomainFromConfig('domains.main')]class MyController{    #[Get('my-get-route')]publicfunctionmyGetMethod()    {    }}

When this is parsed, it will get the value ofdomains.main from the config file andregister the route as follows;

Route::get('my-get-route', [MyController::class,'myGetMethod'])->domain('example.com');

Scoping bindings

When implicitly binding multiple Eloquent models in a single route definition, you may wish to scope the second Eloquent model such that it must be a child of the previous Eloquent model.

By adding theScopeBindings annotation, you can enable this behaviour:

useSpatie\RouteAttributes\Attributes\Get;useSpatie\RouteAttributes\Attributes\ScopeBindings;class MyController{    #[Get('users/{user}/posts/{post}')]    #[ScopeBindings]publicfunctiongetUserPost(User$user,Post$post)    {return$post;    }}

This is akin to using the->scopeBindings() method on the route registrar manually:

Route::get('/users/{user}/posts/{post}',function (User$user,Post$post) {return$post;})->scopeBindings();

By default, Laravel will enabled scoped bindings on a route when using a custom keyed implicit binding as a nested route parameter, such as/users/{user}/posts/{post:slug}.

To disable this behaviour, you can passfalse to the attribute:

#[ScopeBindings(false)]

This is the equivalent of calling->withoutScopedBindings() on the route registrar manually.

You can also use the annotation on controllers to enable implicitly scoped bindings for all its methods. For any methods where you want to override this, you can passfalse to the attribute on those methods, just like you would normally.

Specifying where

You can use theWhere annotation on a class or method to constrain the format of your route parameters.

useSpatie\RouteAttributes\Attributes\Get;useSpatie\RouteAttributes\Attributes\Post;useSpatie\RouteAttributes\Attributes\Where;useSpatie\RouteAttributes\Attributes\WhereAlphaNumeric;#[Where('my-where','[0-9]+')]class MyController{    #[Get('my-get-route/{my-where}')]publicfunctionmyGetMethod()    {    }    #[Post('my-post-route/{my-where}/{my-alpha-numeric}')]    #[WhereAlphaNumeric('my-alpha-numeric')]publicfunctionmyPostMethod()    {    }}

These annotations will automatically register these routes:

Route::get('my-get-route/{my-where}', [MyController::class,'myGetMethod'])->where(['my-where' =>'[0-9]+']);Route::post('my-post-route/{my-where}/{my-alpha-numeric}', [MyController::class,'myPostMethod'])->where(['my-where' =>'[0-9]+','my-alpha-numeric' =>'[a-zA-Z0-9]+']);

For convenience, some commonly used regular expression patterns have helper attributes that allow you to quickly add pattern constraints to your routes.

#[WhereAlpha('alpha')]#[WhereAlphaNumeric('alpha-numeric')]#[WhereIn('in', ['value1','value2'])]#[WhereNumber('number')]#[WhereUlid('ulid')]#[WhereUuid('uuid')]

Specifying a group

You can use theGroup annotation on a class to create multiple groups with different domains and prefixes for the routes of all methods of that class.

useSpatie\RouteAttributes\Attributes\Get;useSpatie\RouteAttributes\Attributes\Post;useSpatie\RouteAttributes\Attributes\Domain;#[Group(domain:'my-subdomain.localhost', prefix:'my-prefix')]#[Group(domain:'my-second-subdomain.localhost', prefix:'my-second-prefix')]class MyController{    #[Get('my-get-route')]publicfunctionmyGetMethod()    {    }    #[Post('my-post-route')]publicfunctionmyPostMethod()    {    }}

These annotations will automatically register these routes:

Route::get('my-get-route', [MyController::class,'myGetMethod'])->prefix('my-prefix')->domain('my-subdomain.localhost');Route::post('my-post-route', [MyController::class,'myPostMethod'])->prefix('my-prefix')->domain('my-subdomain.localhost');Route::get('my-get-route', [MyController::class,'myGetMethod'])->prefix('my-second-prefix')->domain('my-second-subdomain.localhost');Route::post('my-post-route', [MyController::class,'myPostMethod'])->prefix('my-second-prefix')->domain('my-second-subdomain.localhost');

Specifying defaults

You can use theDefaults annotation on a class or method to define the default values of your optional route parameters.

useSpatie\RouteAttributes\Attributes\Defaults;useSpatie\RouteAttributes\Attributes\Get;useSpatie\RouteAttributes\Attributes\Post;#[Defaults('param','controller-default')]class MyControllerextends Controller{    #[Get('my-get-route/{param?}')]publicfunctionmyGetMethod($param)    {    }    #[Post('my-post-route/{param?}/{param2?}')]    #[Defaults('param2','method-default')]publicfunctionmyPostMethod($param,$param2)    {    }    #[Get('my-default-route/{param?}/{param2?}/{param3?}')]    #[Defaults('param2','method-default-first')]    #[Defaults('param3','method-default-second')]publicfunctionmyDefaultMethod($param,$param2,$param3)    {    }    #[Get('my-override-route/{param?}')]    #[Defaults('param','method-default')]publicfunctionmyOverrideMethod($param)    {    }}

These annotations will automatically register these routes:

Route::get('my-get-route/{param?}', [MyController::class,'myGetMethod'])->setDefaults(['param','controller-default']);Route::post('my-post-route/{param?}/{param2?}', [MyController::class,'myPostMethod'])->setDefaults(['param','controller-default','param2' =>'method-default']);Route::get('my-default-route/{param?}/{param2?}/{param3?}', [MyController::class,'myDefaultMethod'])->setDefaults(['param','controller-default','param2' =>'method-default-first','param3' =>'method-default-second']);Route::get('my-override-route/{param?}', [MyController::class,'myOverrideMethod'])->setDefaults(['param','method-default']);

With Trashed

You can use theWithTrashed annotation on a class or method to enable WithTrashed bindings to the model.You can explicitly override the behaviour usingWithTrashed(false) if it is applied at the class level

useSpatie\RouteAttributes\Attributes\Get;useSpatie\RouteAttributes\Attributes\Post;useSpatie\RouteAttributes\Attributes\WithTrashed;#[WithTrashed]class MyControllerextends Controller{    #[Get('my-get-route/{param}')]    #[WithTrashed]publicfunctionmyGetMethod($param)    {    }    #[Post('my-post-route/{param}')]    #[WithTrashed(false)]publicfunctionmyPostMethod($param)    {    }    #[Get('my-default-route/{param}')]publicfunctionmyDefaultMethod($param)    {    }    }

These annotations will automatically register these routes:

Route::get('my-get-route/{param}', [MyController::class,'myGetMethod'])->WithTrashed();Route::post('my-post-route/{param}', [MyController::class,'myPostMethod'])->withTrashed(false);Route::get('my-default-route/{param}', [MyController::class,'myDefaultMethod'])->withTrashed();

Testing

composertest

Changelog

Please seeCHANGELOG for more information on what has changed recently.

Contributing

Please seeCONTRIBUTING for details.

Security Vulnerabilities

Please reviewour security policy on how to report security vulnerabilities.

Credits

License

The MIT License (MIT). Please seeLicense File for more information.

About

Use PHP 8 attributes to register routes in a Laravel app

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • PHP100.0%

[8]ページ先頭

©2009-2025 Movatter.jp