コンテンツへスキップ

ルーティング

基本的なルーティング

最も基本的なLaravelのルートは、URIとクロージャを受け入れ、複雑なルーティング構成ファイルなしで、ルートと動作を定義する非常にシンプルで表現力豊かな方法を提供します。

use Illuminate\Support\Facades\Route;
 
Route::get('/greeting', function () {
return 'Hello World';
});

デフォルトのルートファイル

すべてのLaravelルートは、routesディレクトリにあるルートファイルで定義されます。これらのファイルは、アプリケーションのbootstrap/app.phpファイルで指定された構成を使用して、Laravelによって自動的にロードされます。routes/web.phpファイルは、Webインターフェイス用のルートを定義します。これらのルートには、セッション状態やCSRF保護などの機能を提供するwebミドルウェアグループが割り当てられます。

ほとんどのアプリケーションでは、まずroutes/web.phpファイルにルートを定義することから始めます。routes/web.phpで定義されたルートは、ブラウザで定義されたルートのURLを入力することでアクセスできます。たとえば、ブラウザでhttp://example.com/userに移動すると、次のルートにアクセスできます。

use App\Http\Controllers\UserController;
 
Route::get('/user', [UserController::class, 'index']);

APIルート

アプリケーションがステートレスAPIも提供する場合、install:apiArtisanコマンドを使用してAPIルーティングを有効にできます。

php artisan install:api

install:apiコマンドは、サードパーティのAPIコンシューマー、SPA、またはモバイルアプリケーションの認証に使用できる、堅牢でありながらシンプルなAPIトークン認証ガードを提供するLaravel Sanctumをインストールします。さらに、install:apiコマンドはroutes/api.phpファイルを作成します。

Route::get('/user', function (Request $request) {
return $request->user();
})->middleware('auth:sanctum');

routes/api.phpのルートはステートレスであり、apiミドルウェアグループに割り当てられます。さらに、/apiURIプレフィックスはこれらのルートに自動的に適用されるため、ファイル内のすべてのルートに手動で適用する必要はありません。プレフィックスは、アプリケーションのbootstrap/app.phpファイルを変更することで変更できます。

->withRouting(
api: __DIR__.'/../routes/api.php',
apiPrefix: 'api/admin',
// ...
)

利用可能なルータメソッド

ルーターを使用すると、任意のHTTP動詞に応答するルートを登録できます。

Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);

複数のHTTP動詞に応答するルートを登録する必要がある場合があります。matchメソッドを使用すると、それを行うことができます。または、anyメソッドを使用して、すべてのHTTP動詞に応答するルートを登録することもできます。

Route::match(['get', 'post'], '/', function () {
// ...
});
 
Route::any('/', function () {
// ...
});
lightbulb

同じURIを共有する複数のルートを定義する場合、getpostputpatchdelete、およびoptionsメソッドを使用するルートは、anymatch、およびredirectメソッドを使用するルートの前に定義する必要があります。これにより、着信リクエストが正しいルートと一致することが保証されます。

依存性注入

ルートのコールバックシグネチャで、ルートに必要な依存関係をタイプヒントとして指定できます。宣言された依存関係は、Laravelのサービスコンテナによって自動的に解決され、コールバックに注入されます。たとえば、Illuminate\Http\Requestクラスをタイプヒントとして指定すると、現在のHTTPリクエストがルートコールバックに自動的に注入されます。

use Illuminate\Http\Request;
 
Route::get('/users', function (Request $request) {
// ...
});

CSRF保護

webルートファイルで定義されているPOSTPUTPATCH、またはDELETEルートを指すHTMLフォームには、CSRFトークンフィールドを含める必要があることに注意してください。それ以外の場合、リクエストは拒否されます。CSRF保護の詳細については、CSRFドキュメントを参照してください。

<form method="POST" action="/profile">
@csrf
...
</form>

リダイレクトルート

別のURIにリダイレクトするルートを定義している場合は、Route::redirectメソッドを使用できます。このメソッドは、単純なリダイレクトを実行するために、完全なルートやコントローラーを定義する必要がない便利なショートカットを提供します。

Route::redirect('/here', '/there');

デフォルトでは、Route::redirect302ステータスコードを返します。オプションの3番目のパラメータを使用してステータスコードをカスタマイズできます。

Route::redirect('/here', '/there', 301);

または、Route::permanentRedirectメソッドを使用して301ステータスコードを返すことができます。

Route::permanentRedirect('/here', '/there');
exclamation

リダイレクトルートでルートパラメータを使用する場合、次のパラメータはLaravelによって予約されており、使用できません:destinationstatus

ビュールート

ルートがビューを返すだけでよい場合は、Route::viewメソッドを使用できます。redirectメソッドと同様に、このメソッドは、完全なルートやコントローラーを定義する必要がない簡単なショートカットを提供します。viewメソッドは、最初の引数としてURI、2番目の引数としてビュー名を受け入れます。さらに、オプションの3番目の引数として、ビューに渡すデータの配列を指定できます。

Route::view('/welcome', 'welcome');
 
Route::view('/welcome', 'welcome', ['name' => 'Taylor']);
exclamation

ビュールートでルートパラメータを使用する場合、次のパラメータはLaravelによって予約されており、使用できません:viewdatastatus、およびheaders

ルートの一覧表示

route:listArtisanコマンドを使用すると、アプリケーションで定義されているすべてのルートの概要を簡単に確認できます。

php artisan route:list

デフォルトでは、各ルートに割り当てられているルートミドルウェアは、route:list出力には表示されません。ただし、コマンドに-vオプションを追加することで、ルートミドルウェアとミドルウェアグループ名を表示するようにLaravelに指示できます。

php artisan route:list -v
 
# Expand middleware groups...
php artisan route:list -vv

また、特定のURIで始まるルートのみを表示するようにLaravelに指示することもできます。

php artisan route:list --path=api

さらに、route:listコマンドの実行時に--except-vendorオプションを指定すると、サードパーティのパッケージによって定義されたルートを非表示にするようにLaravelに指示できます。

php artisan route:list --except-vendor

同様に、route:listコマンドの実行時に--only-vendorオプションを指定すると、サードパーティのパッケージによって定義されたルートのみを表示するようにLaravelに指示することもできます。

php artisan route:list --only-vendor

ルーティングのカスタマイズ

デフォルトでは、アプリケーションのルートはbootstrap/app.phpファイルによって構成およびロードされます。

<?php
 
use Illuminate\Foundation\Application;
 
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)->create();

ただし、アプリケーションのルートのサブセットを格納するために、まったく新しいファイルを定義する必要がある場合があります。これを実現するには、withRoutingメソッドにthenクロージャを指定します。このクロージャ内で、アプリケーションに必要な追加のルートを登録できます。

use Illuminate\Support\Facades\Route;
 
->withRouting(
web: __DIR__.'/../routes/web.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
then: function () {
Route::middleware('api')
->prefix('webhooks')
->name('webhooks.')
->group(base_path('routes/webhooks.php'));
},
)

または、withRoutingメソッドにusingクロージャを指定することで、ルート登録を完全に制御することもできます。この引数が渡されると、フレームワークによってHTTPルートは登録されなくなり、すべてのルートを手動で登録する必要があります。

use Illuminate\Support\Facades\Route;
 
->withRouting(
commands: __DIR__.'/../routes/console.php',
using: function () {
Route::middleware('api')
->prefix('api')
->group(base_path('routes/api.php'));
 
Route::middleware('web')
->group(base_path('routes/web.php'));
},
)

ルートパラメータ

必須パラメータ

ルート内でURIのセグメントをキャプチャする必要がある場合があります。たとえば、URLからユーザーのIDをキャプチャする必要がある場合があります。ルートパラメータを定義することで、それを行うことができます。

Route::get('/user/{id}', function (string $id) {
return 'User '.$id;
});

ルートに必要なだけ多くのルートパラメータを定義できます。

Route::get('/posts/{post}/comments/{comment}', function (string $postId, string $commentId) {
// ...
});

ルートパラメータは常に{}中かっこで囲まれ、アルファベット文字で構成する必要があります。アンダースコア(_)もルートパラメータ名の中で使用できます。ルートパラメータは、ルートコールバック/コントローラーの引数の順序に基づいて、ルートコールバック/コントローラーに注入されます。ルートコールバック/コントローラーの引数の名前は関係ありません。

パラメータと依存性注入

Laravelサービスコンテナによってルートのコールバックに自動的に注入したい依存関係がルートにある場合は、依存関係の後にルートパラメータをリストする必要があります。

use Illuminate\Http\Request;
 
Route::get('/user/{id}', function (Request $request, string $id) {
return 'User '.$id;
});

オプションパラメータ

URIに常に存在するとは限らないルートパラメータを指定する必要がある場合があります。パラメータ名の後に?マークを付けることで、それを行うことができます。ルートに対応する変数にデフォルト値を設定してください。

Route::get('/user/{name?}', function (?string $name = null) {
return $name;
});
 
Route::get('/user/{name?}', function (?string $name = 'John') {
return $name;
});

正規表現制約

ルートインスタンスのwhereメソッドを使用すると、ルートパラメータの形式を制約できます。whereメソッドは、パラメータの名前と、パラメータを制約する方法を定義する正規表現を受け取ります。

Route::get('/user/{name}', function (string $name) {
// ...
})->where('name', '[A-Za-z]+');
 
Route::get('/user/{id}', function (string $id) {
// ...
})->where('id', '[0-9]+');
 
Route::get('/user/{id}/{name}', function (string $id, string $name) {
// ...
})->where(['id' => '[0-9]+', 'name' => '[a-z]+']);

便宜上、よく使用されるいくつかの正規表現パターンには、ルートにパターン制約をすばやく追加できるヘルパーメソッドがあります。

Route::get('/user/{id}/{name}', function (string $id, string $name) {
// ...
})->whereNumber('id')->whereAlpha('name');
 
Route::get('/user/{name}', function (string $name) {
// ...
})->whereAlphaNumeric('name');
 
Route::get('/user/{id}', function (string $id) {
// ...
})->whereUuid('id');
 
Route::get('/user/{id}', function (string $id) {
// ...
})->whereUlid('id');
 
Route::get('/category/{category}', function (string $category) {
// ...
})->whereIn('category', ['movie', 'song', 'painting']);
 
Route::get('/category/{category}', function (string $category) {
// ...
})->whereIn('category', CategoryEnum::cases());

受信リクエストがルートパターンの制約と一致しない場合、404 HTTPレスポンスが返されます。

グローバル制約

ルートパラメータを常に特定の正規表現で制約したい場合は、patternメソッドを使用できます。これらのパターンは、アプリケーションのApp\Providers\AppServiceProviderクラスのbootメソッドで定義する必要があります。

use Illuminate\Support\Facades\Route;
 
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Route::pattern('id', '[0-9]+');
}

パターンが定義されると、そのパラメータ名を使用するすべてのルートに自動的に適用されます。

Route::get('/user/{id}', function (string $id) {
// Only executed if {id} is numeric...
});

エンコードされたスラッシュ

Laravelのルーティングコンポーネントでは、/を除くすべての文字がルートパラメータ値内に存在できます。プレースホルダーの一部として/を明示的に許可するには、where条件の正規表現を使用する必要があります。

Route::get('/search/{search}', function (string $search) {
return $search;
})->where('search', '.*');
exclamation

エンコードされたスラッシュは、最後のルートセグメント内でのみサポートされています。

名前付きルート

名前付きルートを使用すると、特定のルートのURLまたはリダイレクトを簡単に生成できます。ルート定義にnameメソッドをチェーンすることで、ルートの名前を指定できます。

Route::get('/user/profile', function () {
// ...
})->name('profile');

コントローラアクションにもルート名を指定できます。

Route::get(
'/user/profile',
[UserProfileController::class, 'show']
)->name('profile');
exclamation

ルート名は常に一意である必要があります。

名前付きルートへのURLの生成

特定のルートに名前を割り当てたら、Laravelのrouteおよびredirectヘルパー関数を使用してURLまたはリダイレクトを生成するときに、ルートの名前を使用できます。

// Generating URLs...
$url = route('profile');
 
// Generating Redirects...
return redirect()->route('profile');
 
return to_route('profile');

名前付きルートがパラメータを定義している場合は、route関数の2番目の引数としてパラメータを渡すことができます。指定されたパラメータは、生成されたURLの正しい位置に自動的に挿入されます。

Route::get('/user/{id}/profile', function (string $id) {
// ...
})->name('profile');
 
$url = route('profile', ['id' => 1]);

配列に追加のパラメータを渡すと、それらのキー/値のペアは、生成されたURLのクエリ文字列に自動的に追加されます。

Route::get('/user/{id}/profile', function (string $id) {
// ...
})->name('profile');
 
$url = route('profile', ['id' => 1, 'photos' => 'yes']);
 
// /user/1/profile?photos=yes
lightbulb

場合によっては、現在のロケールなど、URLパラメータの要求全体にわたるデフォルト値を指定したい場合があります。これを実現するには、URL::defaultsメソッドを使用できます。

現在のルートの検査

現在のリクエストが特定の名前付きルートにルーティングされたかどうかを判断する場合は、Routeインスタンスのnamedメソッドを使用できます。たとえば、ルートミドルウェアから現在のルート名を確認できます。

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
 
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
if ($request->route()->named('profile')) {
// ...
}
 
return $next($request);
}

ルートグループ

ルートグループを使用すると、ミドルウェアなどのルート属性を、個々のルートごとに定義する必要なく、多数のルート間で共有できます。

ネストされたグループは、属性を親グループとインテリジェントに「マージ」しようとします。ミドルウェアとwhere条件はマージされ、名前とプレフィックスは追加されます。名前空間の区切り文字とURIプレフィックスのスラッシュは、必要に応じて自動的に追加されます。

ミドルウェア

ミドルウェアをグループ内のすべてのルートに割り当てるには、グループを定義する前にmiddlewareメソッドを使用できます。ミドルウェアは、配列にリストされている順序で実行されます。

Route::middleware(['first', 'second'])->group(function () {
Route::get('/', function () {
// Uses first & second middleware...
});
 
Route::get('/user/profile', function () {
// Uses first & second middleware...
});
});

コントローラ

ルートのグループがすべて同じコントローラを使用する場合は、controllerメソッドを使用して、グループ内のすべてのルートに共通のコントローラを定義できます。次に、ルートを定義するときは、呼び出すコントローラメソッドのみを指定する必要があります。

use App\Http\Controllers\OrderController;
 
Route::controller(OrderController::class)->group(function () {
Route::get('/orders/{id}', 'show');
Route::post('/orders', 'store');
});

サブドメインルーティング

ルートグループは、サブドメインルーティングを処理するためにも使用できます。サブドメインは、ルートURIと同様にルートパラメータを割り当てることができ、ルートまたはコントローラで使用するためにサブドメインの一部をキャプチャできます。サブドメインは、グループを定義する前にdomainメソッドを呼び出すことで指定できます。

Route::domain('{account}.example.com')->group(function () {
Route::get('/user/{id}', function (string $account, string $id) {
// ...
});
});
exclamation

サブドメインルートに到達できるようにするには、ルートドメインルートを登録する前にサブドメインルートを登録する必要があります。これにより、同じURIパスを持つルートドメインルートがサブドメインルートを上書きするのを防ぎます。

ルートプレフィックス

prefixメソッドを使用すると、グループ内の各ルートに指定されたURIをプレフィックスとして付けることができます。たとえば、グループ内のすべてのルートURIにadminをプレフィックスとして付けたい場合があります。

Route::prefix('admin')->group(function () {
Route::get('/users', function () {
// Matches The "/admin/users" URL
});
});

ルート名プレフィックス

nameメソッドを使用すると、グループ内の各ルート名に指定された文字列をプレフィックスとして付けることができます。たとえば、グループ内のすべてのルートの名前のプレフィックスとしてadminを付けたい場合があります。指定された文字列は、指定されたとおりにルート名のプレフィックスとして付加されるため、プレフィックスに末尾の.文字を指定します。

Route::name('admin.')->group(function () {
Route::get('/users', function () {
// Route assigned name "admin.users"...
})->name('users');
});

ルートモデルバインディング

モデルIDをルートまたはコントローラアクションに挿入する場合、多くの場合、そのIDに対応するモデルを取得するためにデータベースにクエリを実行します。Laravelのルートモデルバインディングは、モデルインスタンスをルートに直接自動的に挿入する便利な方法を提供します。たとえば、ユーザーのIDを挿入する代わりに、指定されたIDに一致するUserモデルインスタンス全体を挿入できます。

暗黙的バインディング

Laravelは、型ヒント付きの変数名がルートセグメント名と一致するルートまたはコントローラアクションで定義されたEloquentモデルを自動的に解決します。例:

use App\Models\User;
 
Route::get('/users/{user}', function (User $user) {
return $user->email;
});

$user変数は、App\Models\User Eloquentモデルとして型ヒントが付けられ、変数名が{user} URIセグメントと一致するため、Laravelは、リクエストURIからの対応する値と一致するIDを持つモデルインスタンスを自動的に挿入します。一致するモデルインスタンスがデータベースに見つからない場合は、404 HTTPレスポンスが自動的に生成されます。

もちろん、コントローラメソッドを使用する場合でも暗黙的なバインディングが可能です。繰り返しますが、{user} URIセグメントが、App\Models\User型ヒントを含むコントローラの$user変数と一致することに注意してください。

use App\Http\Controllers\UserController;
use App\Models\User;
 
// Route definition...
Route::get('/users/{user}', [UserController::class, 'show']);
 
// Controller method definition...
public function show(User $user)
{
return view('user.profile', ['user' => $user]);
}

ソフト削除されたモデル

通常、暗黙的なモデルバインディングは、ソフト削除されたモデルを取得しません。ただし、ルートの定義にwithTrashedメソッドをチェーンすることにより、暗黙的なバインディングにこれらのモデルを取得するように指示できます。

use App\Models\User;
 
Route::get('/users/{user}', function (User $user) {
return $user->email;
})->withTrashed();

キーのカスタマイズ

場合によっては、id以外の列を使用してEloquentモデルを解決したい場合があります。これを行うには、ルートパラメータ定義で列を指定できます。

use App\Models\Post;
 
Route::get('/posts/{post:slug}', function (Post $post) {
return $post;
});

モデルバインディングで、特定のモデルクラスを取得するときにid以外のデータベース列を常に使用する場合は、EloquentモデルのgetRouteKeyNameメソッドをオーバーライドできます。

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

カスタムキーとスコープ

単一のルート定義で複数のEloquentモデルを暗黙的にバインドする場合、2番目のEloquentモデルを、前のEloquentモデルの子である必要があるようにスコープ設定したい場合があります。たとえば、特定のユーザーのブログ投稿をスラッグで取得する次のルート定義について考えてみましょう。

use App\Models\Post;
use App\Models\User;
 
Route::get('/users/{user}/posts/{post:slug}', function (User $user, Post $post) {
return $post;
});

カスタムキー付きの暗黙的なバインディングをネストされたルートパラメータとして使用すると、Laravelは、親のリレーションシップ名を推測する規則を使用して、ネストされたモデルを親で取得するために自動的にクエリをスコープ設定します。この場合、Userモデルには、Postモデルを取得するために使用できるposts(ルートパラメータ名の複数形)という名前のリレーションシップがあると想定されます。

必要に応じて、カスタムキーが提供されていない場合でも、Laravelに「子」バインディングをスコープ設定するように指示できます。これを行うには、ルートを定義するときにscopeBindingsメソッドを呼び出すことができます。

use App\Models\Post;
use App\Models\User;
 
Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) {
return $post;
})->scopeBindings();

または、スコープ設定されたバインディングを使用するように、ルート定義のグループ全体に指示することもできます。

Route::scopeBindings()->group(function () {
Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) {
return $post;
});
});

同様に、withoutScopedBindingsメソッドを呼び出すことで、バインディングをスコープ設定しないようにLaravelに明示的に指示できます。

Route::get('/users/{user}/posts/{post:slug}', function (User $user, Post $post) {
return $post;
})->withoutScopedBindings();

欠落しているモデルの動作のカスタマイズ

通常、暗黙的にバインドされたモデルが見つからない場合は、404 HTTPレスポンスが生成されます。ただし、ルートを定義するときにmissingメソッドを呼び出すことで、この動作をカスタマイズできます。missingメソッドは、暗黙的にバインドされたモデルが見つからない場合に呼び出されるクロージャを受け入れます。

use App\Http\Controllers\LocationsController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redirect;
 
Route::get('/locations/{location:slug}', [LocationsController::class, 'show'])
->name('locations.view')
->missing(function (Request $request) {
return Redirect::route('locations.index');
});

暗黙的なEnumバインディング

PHP 8.1では、Enumのサポートが導入されました。この機能を補完するために、Laravelを使用すると、ルート定義でバッキングEnumに型ヒントを付けることができ、Laravelはそのルートセグメントが有効なEnum値に対応する場合にのみルートを呼び出します。それ以外の場合は、404 HTTPレスポンスが自動的に返されます。たとえば、次のEnumを考えてみましょう。

<?php
 
namespace App\Enums;
 
enum Category: string
{
case Fruits = 'fruits';
case People = 'people';
}

{category}ルートセグメントがfruitsまたはpeopleの場合にのみ呼び出されるルートを定義できます。それ以外の場合、Laravelは404 HTTPレスポンスを返します。

use App\Enums\Category;
use Illuminate\Support\Facades\Route;
 
Route::get('/categories/{category}', function (Category $category) {
return $category->value;
});

明示的なバインディング

モデルバインディングを使用するために、Laravelの暗黙的で規則ベースのモデル解決を使用する必要はありません。ルートパラメータがモデルにどのように対応するかを明示的に定義することもできます。明示的なバインディングを登録するには、ルーターのmodelメソッドを使用して、指定されたパラメータのクラスを指定します。明示的なモデルバインディングは、AppServiceProviderクラスのbootメソッドの先頭で定義する必要があります。

use App\Models\User;
use Illuminate\Support\Facades\Route;
 
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Route::model('user', User::class);
}

次に、{user}パラメータを含むルートを定義します。

use App\Models\User;
 
Route::get('/users/{user}', function (User $user) {
// ...
});

すべての{user}パラメータをApp\Models\Userモデルにバインドしているため、そのクラスのインスタンスがルートに挿入されます。したがって、たとえば、users/1へのリクエストは、IDが1であるデータベースからのUserインスタンスを挿入します。

一致するモデルインスタンスがデータベースに見つからない場合は、404 HTTPレスポンスが自動的に生成されます。

解決ロジックのカスタマイズ

独自のモデルバインディング解決ロジックを定義する場合は、Route::bindメソッドを使用できます。bindメソッドに渡すクロージャは、URIセグメントの値を受け取り、ルートに挿入されるクラスのインスタンスを返す必要があります。繰り返しますが、このカスタマイズは、アプリケーションのAppServiceProviderbootメソッドで行う必要があります。

use App\Models\User;
use Illuminate\Support\Facades\Route;
 
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Route::bind('user', function (string $value) {
return User::where('name', $value)->firstOrFail();
});
}

または、EloquentモデルでresolveRouteBindingメソッドをオーバーライドすることもできます。このメソッドは、URIセグメントの値を受け取り、ルートに挿入されるクラスのインスタンスを返す必要があります。

/**
* Retrieve the model for a bound value.
*
* @param mixed $value
* @param string|null $field
* @return \Illuminate\Database\Eloquent\Model|null
*/
public function resolveRouteBinding($value, $field = null)
{
return $this->where('name', $value)->firstOrFail();
}

ルートが暗黙的なバインディングスコープを使用している場合、resolveChildRouteBindingメソッドは、親モデルの子バインディングを解決するために使用されます。

/**
* Retrieve the child model for a bound value.
*
* @param string $childType
* @param mixed $value
* @param string|null $field
* @return \Illuminate\Database\Eloquent\Model|null
*/
public function resolveChildRouteBinding($childType, $value, $field)
{
return parent::resolveChildRouteBinding($childType, $value, $field);
}

フォールバックルート

Route::fallbackメソッドを使用すると、他のルートが受信リクエストに一致しない場合に実行されるルートを定義できます。通常、処理されないリクエストは、アプリケーションの例外ハンドラーを介して自動的に「404」ページをレンダリングします。ただし、通常はroutes/web.phpファイル内にfallbackルートを定義するため、webミドルウェアグループ内のすべてのミドルウェアがルートに適用されます。必要に応じて、このルートに追加のミドルウェアを自由に追加できます。

Route::fallback(function () {
// ...
});

レート制限

レートリミッタの定義

Laravelには、特定のルートまたはルートグループのトラフィック量を制限するために利用できる強力でカスタマイズ可能なレート制限サービスが含まれています。開始するには、アプリケーションのニーズを満たすレートリミッター構成を定義する必要があります。

レートリミッターは、アプリケーションのApp\Providers\AppServiceProviderクラスのbootメソッド内で定義できます。

use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
 
/**
* Bootstrap any application services.
*/
protected function boot(): void
{
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
});
}

レートリミッターは、RateLimiter ファサードの for メソッドを使って定義します。for メソッドは、レートリミッターの名前と、そのレートリミッターに割り当てられたルートに適用されるべき制限設定を返すクロージャを受け取ります。制限設定は、Illuminate\Cache\RateLimiting\Limit クラスのインスタンスです。このクラスには、制限を素早く定義できるように、便利な「ビルダー」メソッドが含まれています。レートリミッターの名前には、任意の文字列を使用できます。

use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
 
/**
* Bootstrap any application services.
*/
protected function boot(): void
{
RateLimiter::for('global', function (Request $request) {
return Limit::perMinute(1000);
});
}

受信リクエストが指定されたレート制限を超えた場合、Laravelは自動的に429 HTTPステータスコードで応答を返します。レート制限によって返される独自の応答を定義したい場合は、response メソッドを使用できます。

RateLimiter::for('global', function (Request $request) {
return Limit::perMinute(1000)->response(function (Request $request, array $headers) {
return response('Custom response...', 429, $headers);
});
});

レートリミッターのコールバックは、受信したHTTPリクエストのインスタンスを受け取るため、受信リクエストや認証されたユーザーに基づいて、適切なレート制限を動的に構築できます。

RateLimiter::for('uploads', function (Request $request) {
return $request->user()->vipCustomer()
? Limit::none()
: Limit::perMinute(100);
});

レート制限のセグメント化

場合によっては、何らかの任意の値でレート制限をセグメント化したいことがあります。たとえば、特定のルートへのアクセスを、IPアドレスごとに1分間に100回まで許可したい場合があります。これを実現するには、レート制限を構築する際に by メソッドを使用できます。

RateLimiter::for('uploads', function (Request $request) {
return $request->user()->vipCustomer()
? Limit::none()
: Limit::perMinute(100)->by($request->ip());
});

この機能を別の例で説明すると、認証されたユーザーIDごとに1分間に100回、ゲストの場合はIPアドレスごとに1分間に10回、ルートへのアクセスを制限することができます。

RateLimiter::for('uploads', function (Request $request) {
return $request->user()
? Limit::perMinute(100)->by($request->user()->id)
: Limit::perMinute(10)->by($request->ip());
});

複数のレート制限

必要に応じて、特定のレートリミッター構成に対して、レート制限の配列を返すことができます。各レート制限は、配列内の順序に基づいてルートに対して評価されます。

RateLimiter::for('login', function (Request $request) {
return [
Limit::perMinute(500),
Limit::perMinute(3)->by($request->input('email')),
];
});

同一の by 値でセグメント化された複数のレート制限を割り当てる場合は、各 by 値が一意であることを確認する必要があります。これを実現する最も簡単な方法は、by メソッドに渡す値にプレフィックスを付けることです。

RateLimiter::for('uploads', function (Request $request) {
return [
Limit::perMinute(10)->by('minute:'.$request->user()->id),
Limit::perDay(1000)->by('day:'.$request->user()->id),
];
});

ルートへのレートリミッタのアタッチ

レートリミッターは、throttle ミドルウェアを使用して、ルートまたはルートグループにアタッチできます。throttleミドルウェアは、ルートに割り当てるレートリミッターの名前を受け取ります。

Route::middleware(['throttle:uploads'])->group(function () {
Route::post('/audio', function () {
// ...
});
 
Route::post('/video', function () {
// ...
});
});

Redisを使ったスロットリング

デフォルトでは、throttle ミドルウェアは Illuminate\Routing\Middleware\ThrottleRequests クラスにマッピングされています。ただし、Redisをアプリケーションのキャッシュドライバーとして使用している場合は、レート制限の管理にRedisを使用するようにLaravelに指示することができます。これを行うには、アプリケーションの bootstrap/app.php ファイルで throttleWithRedis メソッドを使用する必要があります。このメソッドは、throttle ミドルウェアを Illuminate\Routing\Middleware\ThrottleRequestsWithRedis ミドルウェアクラスにマッピングします。

->withMiddleware(function (Middleware $middleware) {
$middleware->throttleWithRedis();
// ...
})

フォームメソッドのなりすまし

HTMLフォームは PUTPATCH、または DELETE アクションをサポートしていません。したがって、HTMLフォームから呼び出される PUTPATCH、または DELETE ルートを定義する場合は、フォームに隠し _method フィールドを追加する必要があります。_method フィールドで送信された値がHTTPリクエストメソッドとして使用されます。

<form action="/example" method="POST">
<input type="hidden" name="_method" value="PUT">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>

便宜上、@method Blade ディレクティブを使用して、_method 入力フィールドを生成できます。

<form action="/example" method="POST">
@method('PUT')
@csrf
</form>

現在のルートへのアクセス

Route ファサードの currentcurrentRouteName、および currentRouteAction メソッドを使用して、受信リクエストを処理するルートに関する情報にアクセスできます。

use Illuminate\Support\Facades\Route;
 
$route = Route::current(); // Illuminate\Routing\Route
$name = Route::currentRouteName(); // string
$action = Route::currentRouteAction(); // string

Route ファサードの基底クラスRoute インスタンスの両方のAPIドキュメントを参照して、ルーターとルートクラスで使用できるすべてのメソッドを確認できます。

クロスオリジンリソース共有(CORS)

Laravelは、設定した値でCORS OPTIONS HTTPリクエストに自動的に応答できます。OPTIONS リクエストは、アプリケーションのグローバルミドルウェアスタックに自動的に含まれる HandleCors ミドルウェアによって自動的に処理されます。

場合によっては、アプリケーションのCORS構成値をカスタマイズする必要がある場合があります。これは、config:publish Artisan コマンドを使用して cors 設定ファイルを公開することで行うことができます。

php artisan config:publish cors

このコマンドは、アプリケーションの config ディレクトリ内に cors.php 設定ファイルを配置します。

lightbulb

CORSおよびCORSヘッダーの詳細については、MDN WebドキュメントのCORSを参照してください。

ルートキャッシュ

アプリケーションを本番環境にデプロイする場合は、Laravelのルートキャッシュを活用する必要があります。ルートキャッシュを使用すると、アプリケーションのすべてのルートを登録するのにかかる時間が大幅に短縮されます。ルートキャッシュを生成するには、route:cache Artisanコマンドを実行します。

php artisan route:cache

このコマンドを実行すると、キャッシュされたルートファイルがリクエストごとに読み込まれます。新しいルートを追加した場合は、必ず新しいルートキャッシュを生成する必要があることに注意してください。このため、プロジェクトのデプロイ中にのみ route:cache コマンドを実行する必要があります。

ルートキャッシュをクリアするには、route:clear コマンドを使用できます。

php artisan route:clear