DEV Community

Morcos Gad
Morcos Gad

Posted on

Routing Advanced Tips - Laravel

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
Route::resources([
    'campaigns' => 'CampaignController',
    'users' => 'UserController',
    'models' => 'ModelController',
    'trims' => 'TrimController'
], [
    'except' => ['show']
    // you can set here other options e.g. 'only', 'except', 'names', 'middleware'
]);
Enter fullscreen mode Exit fullscreen mode
  • Use only and except when dealing with resources
Route::resource('/test', 'TestController')->only(['index', 'store', 'edit', 'update', 'destroy']);
Route::resource('/test', 'TestController')->except(['create', 'show']);

Enter fullscreen mode Exit fullscreen mode
  • Adding a Custom Attribute to a Route in Laravel
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');
Enter fullscreen mode Exit fullscreen mode

This is a normal route definition. But you can see the first parameter of the group method

['key' => 'value']
Enter fullscreen mode Exit fullscreen mode

This will be added to the route’s action array. So you can obtain it by using a Request instance.

$request->route()->action['key']; // 'value'
Enter fullscreen mode Exit fullscreen mode
  • Route::get() BEFORE Route::resource()
Route::get('photos/popular', 'PhotoController@method');
Route::resource('photos', 'PhotoController');
Enter fullscreen mode Exit fullscreen mode
  • Group in Another Group
// 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');
    });
});
Enter fullscreen mode Exit fullscreen mode
  • 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
Route::group(['prefix' => '{locale}', 'where' => ['locale' => '[a-zA-Z]{2}']], function () {
    Route::get('/', 'HomeController@index');
    Route::get('article/{id}', 'ArticleController@show');
});
Enter fullscreen mode Exit fullscreen mode
Route::domain('{account}.myapp.com')->group(function () {
    Route::get('user/{id}', function ($account, $id) {
        //
    });
});
Enter fullscreen mode Exit fullscreen mode
  • 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 artisan make:model Book -mcr
Enter fullscreen mode Exit fullscreen mode
  • API Routes – from V1 to V2 in app/Providers/RouteServiceProvider.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'));
}
Enter fullscreen mode Exit fullscreen mode

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

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'));
}
Enter fullscreen mode Exit fullscreen mode
Route::middleware('auth:api', 'throttle:60,1')->group(function () {
    Route::get('/user', function () {
        //
    });
});
Enter fullscreen mode Exit fullscreen mode

But did you know you can do it separately for public and for logged-in users?

// maximum of 10 requests per minute for guests 60 for authenticated users
Route::middleware('throttle:10|60,1')->group(function () {
    //
});
Enter fullscreen mode Exit fullscreen mode

Also, you can have a DB field users.rate_limit and limit the amount for specific user

Route::middleware('auth:api', 'throttle:rate_limit,1')->group(function () {
    Route::get('/user', function () {
        //
    });
});
Enter fullscreen mode Exit fullscreen mode
  • Route List and Route Caching you can check your actual route with Artisan command
php artisan route:list
Enter fullscreen mode Exit fullscreen mode

after every change of your routes, you need to launch command

php artisan route:clear
Enter fullscreen mode Exit fullscreen mode

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/

Top comments (0)