> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# パッケージのミドルウェア登録と適用範囲

> Laravel 13のRouter実装から、パッケージのミドルウェアエイリアス登録、明示的な適用、グループの上書き回避とキャッシュ時の検証を解説します。

パッケージにHTTP機能を追加するときは、ミドルウェアを利用可能にすることと、利用アプリケーションのリクエストへ適用することを分けます。インストールだけで全ルートの挙動を変えない設計にすると、導入時の影響と将来の互換性を管理しやすくなります。

このページでは[パッケージ開発の基礎](/jp/advanced/package-development)を前提に、Laravel公式ドキュメントの `13.x` とFramework `v13.36.0` の実装を参照します。通常のミドルウェアの書き方は[ミドルウェア](/jp/middleware)を参照してください。

## 登録・適用・実行を分ける

`Router::aliasMiddleware()` は、エイリアスをキー、クラス名を値としてRouterの配列へ登録します。ミドルウェアのインスタンス生成や、ルートへの適用は行いません。

```mermaid theme={null}
flowchart TD
    A["プロバイダーのboot"] --> B["aliasMiddlewareで<br>名前とクラスを登録"]
    C["ルート定義"] --> D["middlewareで<br>適用する名前を指定"]
    B --> E["リクエストのルートが決まる"]
    D --> E
    E --> F["エイリアス・グループを展開<br>除外と優先順位を反映"]
    F --> G["Pipelineがミドルウェアを実行"]
```

| 操作 | 役割 | それだけでは行われないこと |
| - | - | - |
| `aliasMiddleware()` | 名前からクラスへの対応を登録する | リクエストへの適用 |
| ルートの `middleware()` | 対象ルートへ割り当てる | ミドルウェアクラスの独自実装 |
| `middlewareGroup()` | 名前付きグループの内容を設定する | グローバルミドルウェアへの追加 |
| HTTP Kernelのグローバルスタックへの追加 | 全リクエストを対象にする | ルート単位の除外への対応 |

エイリアス名は公開APIです。`auth` や `throttle` のような組み込み名、他のパッケージと衝突しやすい一般名を避け、パッケージ固有のプレフィックスを付けます。同じキーへ再登録すると、`aliasMiddleware()` は以前の対応を上書きします。

## プロバイダーでエイリアスを公開する

次の例では、レスポンスに固定の識別ヘッダーを付けるミドルウェアを作ります。認証・認可やアクセス制御の例ではありません。ComposerのPSR-4で `Acme\Courier\` を `src/` に対応させ、プロバイダーを[自動検出](/jp/advanced/package-discovery)または手動で登録することを前提にします。

```php src/Http/Middleware/AddCourierHeader.php theme={null}
<?php

namespace Acme\Courier\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class AddCourierHeader
{
    public function handle(Request $request, Closure $next): Response
    {
        $response = $next($request);

        $response->headers->set('X-Acme-Courier', 'enabled');

        return $response;
    }
}
```

Routerの利用は `boot()` で行います。`boot()` の引数はサービスコンテナから注入されるため、ミドルウェアの登録のために利用者の `bootstrap/app.php` を自動編集する必要はありません。

```php src/CourierServiceProvider.php theme={null}
<?php

namespace Acme\Courier;

use Acme\Courier\Http\Middleware\AddCourierHeader;
use Illuminate\Routing\Router;
use Illuminate\Support\ServiceProvider;

class CourierServiceProvider extends ServiceProvider
{
    public function boot(Router $router): void
    {
        $router->aliasMiddleware('acme-courier.header', AddCourierHeader::class);
    }
}
```

このプロバイダーは通常のプロバイダーとして起動させます。エイリアスの登録を、別サービスが解決された場合だけ実行する遅延プロバイダーへ移すと、ルートが必要とする時点で登録される保証がなくなります。

### 利用者がルート単位で適用する

利用アプリケーションの `routes/web.php` で、必要なルートにだけ割り当てます。

```php routes/web.php theme={null}
<?php

use Illuminate\Support\Facades\Route;

Route::get('/courier-status', function () {
    return response()->json(['available' => true]);
})->middleware('acme-courier.header');
```

エイリアスを提供せず、`->middleware(AddCourierHeader::class)` のようにクラス名を直接指定することもできます。短い名前を利用者に提供する必要があるかで選びます。

パッケージ自身がルートを提供する場合も、ルートファイルで必要なミドルウェアを明示します。`loadRoutesFrom()` は `web` や `api` を自動追加しません。登録方法とルートキャッシュの扱いは[パッケージのルート登録とキャッシュ](/jp/advanced/package-routes)を参照してください。

## アプリケーション全体への適用は利用者が選ぶ

利用アプリケーションのすべての `web` ルートへ適用したい場合は、利用者が既存の `withMiddleware()` コールバックに次の設定を追加します。既存の設定を置き換える例ではありません。

```php theme={null}
use Acme\Courier\Http\Middleware\AddCourierHeader;
use Illuminate\Foundation\Configuration\Middleware;

->withMiddleware(function (Middleware $middleware): void {
    $middleware->web(append: [
        AddCourierHeader::class,
    ]);
})
```

この構成ではクラス名を直接使うため、エイリアスの登録順序に依存しません。適用範囲は `web` グループであり、グローバルスタックではありません。`api` や、どちらのグループも付いていないルートへは自動適用されません。

<Warning>
  パッケージのインストール時に `web` 全体へ適用する設計と、利用者が明示的に適用する設計は互換ではありません。認証、セッション、レスポンスヘッダー、外部通信などに影響する処理を、自動更新で全ルートへ広げないでください。
</Warning>

## Routerのグループ操作には差がある

パッケージが独自のグループを提供する場合は、固有の名前を使います。次はプロバイダーの `boot(Router $router)` 内に置く例です。

```php theme={null}
$router->middlewareGroup('acme-courier', [
    AddCourierHeader::class,
]);
```

利用者は `->middleware('acme-courier')` で適用できます。ただし、このグループに含まれるのは指定したクラスだけであり、`web` のセッションやCSRF保護を引き継ぐものではありません。

既存グループへ追加するAPIもありますが、`v13.36.0` のRouter実装では次の違いがあります。

| Routerのメソッド | グループが存在する場合 | グループが存在しない場合 |
| - | - | - |
| `middlewareGroup($name, $items)` | 配列全体を置き換える | 指定配列で作る |
| `pushMiddlewareToGroup($name, $item)` | 同じ項目がなければ末尾へ追加 | 空の配列を作ってから追加する |
| `prependMiddlewareToGroup($name, $item)` | 同じ項目がなければ先頭へ追加 | 何もしない |

`middlewareGroup('web', [...])` でパッケージのクラスだけを設定すると、既存の `web` の内容を置き換えてしまいます。追加用のメソッドと混同しないでください。また、存在しない `web` へ `pushMiddlewareToGroup()` しても、標準の `web` グループが復元されるわけではありません。

追加用メソッドの重複判定は登録した値に対するものです。同じクラスを指すエイリアスとクラス名は異なる文字列なので、登録表の段階では別項目になります。表記を統一し、異なる表記の同一クラスまで登録時に重複排除されるとは想定しないでください。

### 登録順序だけで実行順序を保証しない

Routerは、ルートに割り当てられたミドルウェアのエイリアスとグループを展開し、除外を処理してから優先順位で並べ替えます。先頭・末尾への追加だけで、認証やルートモデルバインディングとの厳密な前後関係が保証されるわけではありません。

さらに、HTTP Kernelの `syncMiddlewareToRouter()` は、Kernelが持つグループをRouterへ `middlewareGroup()` で同期します。Kernel側の構成が後から再同期されると、Routerへ直接追加したグループの内容が置き換わる場合があります。パッケージ間の起動順序で既存グループの変更を競うのではなく、利用アプリケーション側の `withMiddleware()` で構成を集約する方針を基本にします。

セッション開始後、認証後などの順序が必要な機能では、その前提をインストール手順に明記し、利用アプリケーションの優先順位設定と合わせて確認します。パッケージがアプリケーション全体の優先順位リストを丸ごと置き換えることは避けてください。

## キャッシュと検証の境界

エイリアス登録を `routesAreCached()` の条件内やルートファイルへ置かないでください。`loadRoutesFrom()` はキャッシュがあるとルートファイルを読み込みませんが、キャッシュされたルートに残るエイリアスを実行時に解決するための登録は必要です。プロバイダーの `boot()` で毎回登録します。

ルートへの割り当てを変更した場合は、利用アプリケーションでルートキャッシュを再作成します。

```bash theme={null}
php artisan route:cache
php artisan route:list --path=courier-status -vv
```

`-vv` はグループの内容を展開して確認するために使います。ただし、一覧表示が成功しても、ミドルウェア内の処理やセッションの利用まで保証するものではありません。HTTPリクエストのテストも必要です。

次は、上記の `/courier-status` を定義したLaravelアプリケーションのFeatureテストへ追加するメソッドです。

```php theme={null}
public function test_courier_header_is_applied(): void
{
    $this->get('/courier-status')
        ->assertOk()
        ->assertHeader('X-Acme-Courier', 'enabled');
}
```

| 確認ケース | 期待する結果 |
| - | - |
| エイリアスを登録しただけのルート | ヘッダーは付かない |
| エイリアスを割り当てたルート | ヘッダーが付く |
| クラス名を直接割り当てたルート | 同じ動作になる |
| キャッシュ作成後に新しいアプリケーションを起動 | 同じルートで同じ動作になる |
| `web` 全体への適用を選択 | 対象の `web` ルートに適用され、対象外には広がらない |
| 利用アプリケーション独自のグループ・優先順位を設定 | セッション・認証・バインディングとの順序が要件を満たす |

グループの存在確認やエイリアスの配列を調べる単体テストと、実際のHTTP実行は別の検証です。特にキャッシュ検証は、同じプロセスのRouterを眺めるだけでなく、キャッシュ作成後の新しい起動で行います。長寿命ワーカーを利用している場合は、通常のデプロイ手順に従って再読み込みしてください。

## 関連ページ

<Columns cols={2}>
  <Card title="ミドルウェア" icon="layer-group" href="/jp/middleware">
    作成、ルートへの適用、パラメーター、優先順位の基本を確認します。
  </Card>

  <Card title="パッケージのルート登録とキャッシュ" icon="route" href="/jp/advanced/package-routes">
    ルートの読み込みとキャッシュ作成時の設定の関係を確認します。
  </Card>
</Columns>

## 参照した一次情報

* [Laravel公式ドキュメント: ミドルウェア](https://github.com/laravel/docs/blob/6bb0a3be3c623f7964c8277625a07b6df7f1de2e/middleware.md)
* [Laravel公式ドキュメント: サービスプロバイダーのbootと依存注入](https://github.com/laravel/docs/blob/6bb0a3be3c623f7964c8277625a07b6df7f1de2e/providers.md#the-boot-method)
* [Router: エイリアス登録・グループ操作・ミドルウェアの展開と整列](https://github.com/laravel/framework/blob/v13.36.0/src/Illuminate/Routing/Router.php)
* [HTTP Kernel: syncMiddlewareToRouter](https://github.com/laravel/framework/blob/v13.36.0/src/Illuminate/Foundation/Http/Kernel.php)


## Related topics

- [Laravelパッケージ開発](/jp/advanced/package-development.md)
- [応用トピック](/jp/advanced/index.md)
- [パッケージのルート登録とキャッシュ](/jp/advanced/package-routes.md)
- [Laravel Fetch Metadata](/jp/packages/laravel-fetch-metadata.md)
- [ミドルウェア](/jp/middleware.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.