13.x とFramework v13.36.0 の実装を参照します。通常のミドルウェアの書き方はミドルウェアを参照してください。
登録・適用・実行を分ける
Router::aliasMiddleware() は、エイリアスをキー、クラス名を値としてRouterの配列へ登録します。ミドルウェアのインスタンス生成や、ルートへの適用は行いません。
エイリアス名は公開APIです。
auth や throttle のような組み込み名、他のパッケージと衝突しやすい一般名を避け、パッケージ固有のプレフィックスを付けます。同じキーへ再登録すると、aliasMiddleware() は以前の対応を上書きします。
プロバイダーでエイリアスを公開する
次の例では、レスポンスに固定の識別ヘッダーを付けるミドルウェアを作ります。認証・認可やアクセス制御の例ではありません。ComposerのPSR-4でAcme\Courier\ を src/ に対応させ、プロバイダーを自動検出または手動で登録することを前提にします。
src/Http/Middleware/AddCourierHeader.php
boot() で行います。boot() の引数はサービスコンテナから注入されるため、ミドルウェアの登録のために利用者の bootstrap/app.php を自動編集する必要はありません。
src/CourierServiceProvider.php
利用者がルート単位で適用する
利用アプリケーションのroutes/web.php で、必要なルートにだけ割り当てます。
routes/web.php
->middleware(AddCourierHeader::class) のようにクラス名を直接指定することもできます。短い名前を利用者に提供する必要があるかで選びます。
パッケージ自身がルートを提供する場合も、ルートファイルで必要なミドルウェアを明示します。loadRoutesFrom() は web や api を自動追加しません。登録方法とルートキャッシュの扱いはパッケージのルート登録とキャッシュを参照してください。
アプリケーション全体への適用は利用者が選ぶ
利用アプリケーションのすべてのweb ルートへ適用したい場合は、利用者が既存の withMiddleware() コールバックに次の設定を追加します。既存の設定を置き換える例ではありません。
web グループであり、グローバルスタックではありません。api や、どちらのグループも付いていないルートへは自動適用されません。
Routerのグループ操作には差がある
パッケージが独自のグループを提供する場合は、固有の名前を使います。次はプロバイダーのboot(Router $router) 内に置く例です。
->middleware('acme-courier') で適用できます。ただし、このグループに含まれるのは指定したクラスだけであり、web のセッションやCSRF保護を引き継ぐものではありません。
既存グループへ追加するAPIもありますが、v13.36.0 のRouter実装では次の違いがあります。
middlewareGroup('web', [...]) でパッケージのクラスだけを設定すると、既存の web の内容を置き換えてしまいます。追加用のメソッドと混同しないでください。また、存在しない web へ pushMiddlewareToGroup() しても、標準の web グループが復元されるわけではありません。
追加用メソッドの重複判定は登録した値に対するものです。同じクラスを指すエイリアスとクラス名は異なる文字列なので、登録表の段階では別項目になります。表記を統一し、異なる表記の同一クラスまで登録時に重複排除されるとは想定しないでください。
登録順序だけで実行順序を保証しない
Routerは、ルートに割り当てられたミドルウェアのエイリアスとグループを展開し、除外を処理してから優先順位で並べ替えます。先頭・末尾への追加だけで、認証やルートモデルバインディングとの厳密な前後関係が保証されるわけではありません。 さらに、HTTP KernelのsyncMiddlewareToRouter() は、Kernelが持つグループをRouterへ middlewareGroup() で同期します。Kernel側の構成が後から再同期されると、Routerへ直接追加したグループの内容が置き換わる場合があります。パッケージ間の起動順序で既存グループの変更を競うのではなく、利用アプリケーション側の withMiddleware() で構成を集約する方針を基本にします。
セッション開始後、認証後などの順序が必要な機能では、その前提をインストール手順に明記し、利用アプリケーションの優先順位設定と合わせて確認します。パッケージがアプリケーション全体の優先順位リストを丸ごと置き換えることは避けてください。
キャッシュと検証の境界
エイリアス登録をroutesAreCached() の条件内やルートファイルへ置かないでください。loadRoutesFrom() はキャッシュがあるとルートファイルを読み込みませんが、キャッシュされたルートに残るエイリアスを実行時に解決するための登録は必要です。プロバイダーの boot() で毎回登録します。
ルートへの割り当てを変更した場合は、利用アプリケーションでルートキャッシュを再作成します。
-vv はグループの内容を展開して確認するために使います。ただし、一覧表示が成功しても、ミドルウェア内の処理やセッションの利用まで保証するものではありません。HTTPリクエストのテストも必要です。
次は、上記の /courier-status を定義したLaravelアプリケーションのFeatureテストへ追加するメソッドです。
グループの存在確認やエイリアスの配列を調べる単体テストと、実際のHTTP実行は別の検証です。特にキャッシュ検証は、同じプロセスのRouterを眺めるだけでなく、キャッシュ作成後の新しい起動で行います。長寿命ワーカーを利用している場合は、通常のデプロイ手順に従って再読み込みしてください。
関連ページ
ミドルウェア
作成、ルートへの適用、パラメーター、優先順位の基本を確認します。
パッケージのルート登録とキャッシュ
ルートの読み込みとキャッシュ作成時の設定の関係を確認します。