Paulund
2018-07-29 #laravel

Laravel Routing Tips

Group Method Can Use A File Path

If your Laravel route file is becoming too large you can pass in a file path to the route group() method.

This allows you to split up the web routes file into different files.

Route::prefix('account')->group(base_path('routes/account.php'));

Now update the routes/account.php file with all the routes for the user account section.

Route Caching

Laravel can cache your routes to make it quicker to find the code to run.

Just run the command php artisan route:cache.

The problem you might find with this is that you can now cache route closures therefore you will need to change any closures to call methods on controllers.

If you need to remove route caching you can use the command php artisan route:clear

View this article to see the different with and without route caching Laravel route caching performance

Define A Namespace

If you have a group of routes that all have the same namespace you can prefix the namespace within the group by using a namespace method.

For example if you create a user Account area and have controllers for Account/ProfileController and Account/OrdersController, you can group these together with the following.

Route::namespace('Account')
    ->prefix('account')
    ->group(function () {
        Route::get('profile', 'ProfileController');
        Route::get('orders', 'OrdersController');
    });

Debugging Routes

Using artisan you can list out all the registered routes in your application you can use the command php artisan route:list.

This is a quick way of viewing the name of the route and middleware used on the different routes.

Route Model Binding

If you have a route that will show a user profile you might do something like pass in the ID into the route, search the database for the user, if the user doesn't exist throw a 404 error, if the user does exist return the user model to the view. It will look something like below.

public function show($id)
{      
    $user = User:findOrFail($id);

    return view('user.show', compact('user'));
}

Using Laravel implicit binding there is a better way to handle this sort of request. Instead of telling the router we're going to use an ID we can instead tell it we're going to use a user.

// Users
Route::group(['prefix' => 'user'], function(){
    Route::get('/', 'UserController@index');
    Route::get('/create', 'UserController@create');
    Route::post('/store', 'UserController@store');
    Route::get('/{user}', 'UserController@show');
    Route::patch('/{user}', 'UserController@update');
    Route::delete('/{user}', 'UserController@delete');
});

Then in the controller show method we can type-hint the user model to the {user} parameter and Laravel will automatically lookup the User model using the primary key of the model and the parameter passed in the router. Now our show method looks like this.

public function show(User $user)
{      
    return view('user.show', compact('user'));
}

By default this to search for the User by using the primary key but you can change this to use say a slug parameter by using the method getRouteKeyName.

/**
 * Get the route key for the model.
 *
 * @return string
 */
public function getRouteKeyName()
{
    return 'slug';
}

Create A Custom Route File

Laravel defines it's routes via the app/Providers/RouteServiceProvider class.

Inside this class there's a map method that used to point to which files to load the routes from.

By default there are 2 route files it uses, API and Web routes.

    /**
     * Define the routes for the application.
     *
     * @return void
     */
    public function map()
    {
        $this->mapApiRoutes();
        $this->mapWebRoutes();
        //
    }

This will then load the routes from the route folder.

    /**
     * Define the "web" routes for the application.
     *
     * These routes all receive session state, CSRF protection, etc.
     *
     * @return void
     */
    protected function mapWebRoutes()
    {
        Route::middleware('web')
             ->namespace($this->namespace)
             ->group(base_path('routes/web.php'));
    }

To have a custom route file create a new file inside the routes folder, for example we're going to create new routes for the admin area.

Then add a new method into the map method $this->mapAdminRoutes();, then in the RouteServiceProvider create a new method mapAdminRoutes to load the admin routes.

    /**
     * Define the "admin" routes for the application.
     *
     * @return void
     */
    protected function mapAdminRoutes()
    {
        Route::middleware('admin')
             ->namespace($this->namespace . '\Admin')
             ->group(base_path('routes/admin.php'));
    }

Now you can add all your admin routes into this new file.