【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つの基準でまとめることができます。それぞれをメソッドチェーンでつなぐことで、複数の基準で一気にグループ化が可能です。
うまく階層構造を作り、楽に管理できるようにしましょう!
