Routing Advanced Tips - Laravel
Tags: php, laravel, webdev, programming
Published: 2022-02-23 14:00:16

I found some great resources that give me some powerful advice when writing a route and I wanted to share them with you for your future projects.
- Use more than one resources and Controller in one resources
```php
Route::resources([
    'campaigns' => 'CampaignController',
    'users' => 'UserController',
    'models' => 'ModelController',
    'trims' => 'TrimController'
], [
    'except' => ['show']
    // you can set here other options e.g. 'only', 'except', 'names', 'middleware'
]);
```
- Use only and except when dealing with resources
```php
Route::resource('/test', 'TestController')->only(['index', 'store', 'edit', 'update', 'destroy']);
Route::resource('/test', 'TestController')->except(['create', 'show']);

```
- Adding a Custom Attribute to a Route in Laravel
```php
Route::as('admin.')->prefix('admin')->group(['key' => 'value'], function ($router) {
    $router->get('dashboard', DashboardController::class)->name('dashboard');
    $router->get('profile', ProfileController::class)->name('profile');
})->middleware('auth');
```
This is a normal route definition. But you can see the first parameter of the group method
```php
['key' => 'value']
```
This will be added to the route’s action array. So you can obtain it by using a Request instance.
```php
$request->route()->action['key']; // 'value'
```
- Route::get() BEFORE Route::resource()
```php
Route::get('photos/popular', 'PhotoController@method');
Route::resource('photos', 'PhotoController');
```
- Group in Another Group
```php
// public routes
Route::get('/', 'HomeController@index');

// Logged-in users - with "auth" middleware
Route::group(['middleware' => ['auth']], function () {

    // /user/XXX: In addition to "auth", this group will have middleware "simple_users"
    Route::group(['middleware' => ['simple_users'], 'prefix' => 'user'], function () {
        Route::resource('tasks', 'TaskController');
    });

    // /admin/XXX: This group won't have "simple_users", but will have "auth" and "admins"
    Route::group(['middleware' => ['admins'], 'prefix' => 'admin'], function () {
        Route::resource('users', 'UserController');
    });
});
```
- Route Parameter Validation – Multi-Language
The main part here is ‘where’ => [‘locale’ => ‘[a-zA-Z]{2}’] where we use a regular expression to match only two-letter combinations
```php
Route::group(['prefix' => '{locale}', 'where' => ['locale' => '[a-zA-Z]{2}']], function () {
    Route::get('/', 'HomeController@index');
    Route::get('article/{id}', 'ArticleController@show');
});
```
- Dynamic Subdomain Routing
https://laravel.com/docs/master/routing#route-group-subdomain-routing
Note that {account} automatically is passed as $account parameter in all inside controllers methods, so you need to accept that in all of them, don’t forget.
```php
Route::domain('{account}.myapp.com')->group(function () {
    Route::get('user/{id}', function ($account, $id) {
        //
    });
});
```
- Be Careful with Non-English Route Model Binding
But in the database, all names should all be in English, so Laravel “magic” could work between singular and plural, right?

So if you generate a model Book with migration and Controller, you may have this comman
```php
php artisan make:model Book -mcr
```
- API Routes – from V1 to V2
in app/Providers/RouteServiceProvider.php
```php
public function map()
{
    $this->mapApiRoutes();

    $this->mapWebRoutes();

    // ...
}

protected function mapWebRoutes()
{
    Route::middleware('web')
        ->namespace($this->namespace)
        ->group(base_path('routes/web.php'));
}

protected function mapApiRoutes()
{
    Route::prefix('api')
        ->middleware('api')
        ->namespace($this->namespace)
        ->group(base_path('routes/api.php'));
}
```
As you can see, API routes are registered in a separate function with prefix api/.
So, if you want to create V2 route group, you can create a separate routes/api_v2.php and do this
```php
public function map()
{
    // ... older functions

    $this->mapApiV2Routes();
}

// And new function
protected function mapApiV2Routes()
{
    Route::prefix('api/V2')
        ->middleware('api')
        ->namespace($this->namespace)
        ->group(base_path('routes/api_v2.php'));
}
```
- Rate Limiting – Global and for Guests/Users
https://laravel.com/docs/master/routing#rate-limiting
First, you can limit some URL to be called a maximum of 60 times per minute, with throttle:60,1.
```php
Route::middleware('auth:api', 'throttle:60,1')->group(function () {
    Route::get('/user', function () {
        //
    });
});
```
But did you know you can do it separately for public and for logged-in users?
```php
// maximum of 10 requests per minute for guests 60 for authenticated users
Route::middleware('throttle:10|60,1')->group(function () {
    //
});
```
Also, you can have a DB field users.rate_limit and limit the amount for specific user
```php
Route::middleware('auth:api', 'throttle:rate_limit,1')->group(function () {
    Route::get('/user', function () {
        //
    });
});
```
- Route List and Route Caching
you can check your actual route with Artisan command
```php
php artisan route:list
```
after every change of your routes, you need to launch command
```php
php artisan route:clear
```

I hope you enjoyed the code and also if you want to dig deeper, visit these sources that will strengthen your future with route
https://pineco.de/adding-a-custom-attribute-to-a-route-in-laravel/
https://blog.quickadminpanel.com/laravel-routing-8-advanced-tips-languages-apis-groups-validation/