メインコンテンツまでスキップ

ルーティング

基本的なルーティング

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

    use Illuminate\Support\Facades\Route;

Route::get('/greeting', function () {
return 'Hello World';
});

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

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

ほとんどのアプリケーションでは、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:api Artisan コマンドを使用して API ルーティングを有効にすることができます:

php artisan install:api

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

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

routes/api.php のルートは状態を持たず、api ミドルウェアグループに割り当てられます。さらに、これらのルートには /api URI プレフィックスが自動的に適用されるため、ファイル内のすべてのルートに手動で適用する必要はありません。プレフィックスは、アプリケーションの 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 () {
// ...
});

注記

同じ URI を共有する複数のルートを定義する際には、getpostputpatchdeleteoptions メソッドを使用するルートを、anymatchredirect メソッドを使用するルートよりも先に定義する必要があります。これにより、受信したリクエストが正しいルートに一致することが保証されます。

依存性注入

    use Illuminate\Http\Request;

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

CSRF Protection

POSTPUTPATCH、またはDELETEルートを指すHTMLフォームは、webルートファイルで定義されている場合、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');

警告

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

ビュールート

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

    Route::view('/welcome', 'welcome');

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

警告

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

ルートのリスト表示

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

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', '.*');

警告

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

名前付きルート

名前付きルートを使用すると、特定のルートの URL またはリダイレクトを便利に生成できます。ルートに名前を指定するには、name メソッドをルート定義に連結します:

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

また、コントローラーアクションにルート名を指定することもできます:

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

警告

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

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

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

    // Generating URLs...
$url = route('profile');

// Generating Redirects...
return redirect()->route('profile');

return to_route('profile');

名前付きルートがパラメータを定義している場合、route 関数の第二引数としてパラメータを渡すことができます。指定したパラメータは、生成された 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

注記

時々、現在のロケールなどの 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) {
// ...
});
});

警告

サブドメインルートに到達できるようにするためには、サブドメインルートをルートドメインルートよりも先に登録する必要があります。これにより、同じ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 から対応する値を持つモデルインスタンスを自動的に注入します。データベースに一致するモデルインスタンスが見つからない場合、自動的に 404 HTTP レスポンスが生成されます。

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

    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';
}

カスタムキーとスコープ

1つのルート定義で複数の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モデルにpostsという名前のリレーションシップがあると仮定され、それを使用してPostモデルを取得できます。

必要に応じて、ルートを定義する際に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');
});

暗黙の列挙型バインディング

PHP 8.1 では、列挙型のサポートが導入されました。この機能を補完するために、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')),
];
});

ルートにレート制限をアタッチする

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

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

Route::post('/video', function () {
// ...
});
});

Redis を使用したスロットリング

デフォルトでは、throttle ミドルウェアは Illuminate\Routing\Middleware\ThrottleRequests クラスにマップされています。ただし、アプリケーションのキャッシュドライバーとして Redis を使用している場合は、Laravel に Redis を使用してレート制限を管理するよう指示することができます。これを行うには、アプリケーションの 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構成ファイルを配置します。

注記

CORSとCORSヘッダーに関する詳細情報については、MDN web documentation on CORSを参照してください。

ルートキャッシュ

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

php artisan route:cache

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

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

php artisan route:clear