【Laravel】 ルートをグルーピングして整理しよう

ルートは、グループ化することができます。例えば、途中まで共通のパスを持つ、共通のミドルウェアを使用するなどです。

グループ化する

グループは様々な基準で作る子ができます。

  • パス
  • name
  • ミドルウェア
  • where

それぞれでどのようにグループ化するか見ていきましょう。

パスでグループ化

例えば、/user/{id}/user/{id}/friends/user/{id}/messagesのように、共通のパスを持つことはしばしばあります。

その場合、Route::prefix('path')->group(function () {/* ルート一覧 */})のように書きます。

use App\Http\Controllers\UserController;

Route::prefix('user/{id}')->group(function() {
    // user/{id}
    Route::get('/', [UserController::class, 'index']);

    // user/{id}/friends
    Route::get('/friends', [UserController::class, 'friends']);
});

グループは重ねることができます。

Route::prefix('user')->group(function() {
    // user/search
    Route::get('search', [UserController::class, 'search']);

    Route::prefix('{id}')->group(function() {
        // user/{id}
        Route::get('/', [UserController::class, 'index']);
    
        // user/{id}/friends
        Route::get('/friends', [UserController::class, 'friends']);
    });
});

nameをグループ化

nameをグループ化する場合、Route::name('name.')->group(/*...*/)のようにします。

name.のように.が必要となることに注意が必要です。

Route::name('user.')->group(function() {
    // user.search
    Route::get('user/search', [UserController::class, 'search'])->name('search');

    // user.index
    Route::get('user/{id}', [UserController::class, 'index'])->name('index');

    // user.friends
    Route::get('user/{id}/friends', [UserController::class, 'friends'])->name('friends');
});

nameの代わりにasでも同じ動作になります。

middlewareでグループ化

特定のグループで共通のmiddlewareを適用する場合はRoute::middleware([/*...*/])->group(/*...*/)のようにします。

同様に、適用したくないミドルウェアはwithoutMiddlewareを使用します。

Route::middleware([\App\Http\Middleware\IpRestriction::class])->group(function() {
    Route::get('/home', [HelloController::class, 'index']);
});

whereでグループ化

ルートパラメータに同じ規則を適用したい場合、whereを使用します。

ここで、普通のルートに指定したwhereとは微妙に違い、連想配列でしか指定できません。

Route::prefix('user/{id}')->group(function() {
    Route::where(['id' => '[0-9]+'])->group(function() {
        Route::get('/', [UserController::class, 'index']);
        Route::get('/friends', [UserController::class, 'friends']);
    });
});

1つのグループで同時にグルーピングする

例えば、パスでグルーピングすると同時に、nameも同時にグループ化したい等ということはよくあります。その場合、Route::prefix('user')->name('user.')->group(/*...*/)のようにメソッドチェーンでつなげます。

Route::prefix('user')->name('user.')->group(function() {
    // パスは user/search nameは user.search
    Route::get('search', [UserController::class, 'search'])->name('search');

    Route::prefix('{id}')->group(function() {
        // パスは user/{id} nameは user.index
        Route::get('/', [UserController::class, 'index'])->name('index');
    
        // パスは user/{id}/friends nameは user.friends
        Route::get('/friends', [UserController::class, 'friends'])->name('friends');
    });
});

Route::prefix('admin')->name('admin.')->middleware([\App\Http\Middleware\IpRestriction::class])->group(function() {
    /* ... */
});

groupメソッドでグループ化

これまではそれぞれ専用のメソッドでグループ化しましたが、groupメソッドではそれらを一括指定することもできます。

第1引数にグループ化の基準となる連想配列を入れ、キーに種類を入れます。第2引数にルート一覧を入れます。

ここで、nameのグルーピングではnameではなくasを使う必要があります。

Route::group(['prefix' => 'user', 'as' => 'user.'], function () {
    Route::get('search', [UserController::class, 'search'])->name('search');

    Route::group(['prefix' => '{id}', 'where' => ['id' => '[0-9]+']], function () {
        Route::get('/', [UserController::class, 'index'])->name('index');
        Route::get('/friends', [UserController::class, 'friends'])->name('friends');
    });
});

まとめ

ルートは、パス、name、ミドルウェア、whereの4つの基準でまとめることができます。それぞれをメソッドチェーンでつなぐことで、複数の基準で一気にグループ化が可能です。

うまく階層構造を作り、楽に管理できるようにしましょう!

laravel route group thumb

役に立ったらシェアしよう!