# 機能設計書 20-コントローラディスパッチャー

## 概要

本ドキュメントは、Laravel Frameworkのコントローラディスパッチャー（ControllerDispatcher）およびCallableDispatcher機能の設計を詳細に記述したものである。ルートにマッチしたコントローラメソッドまたはクロージャを実行し、依存性の解決とミドルウェアの取得を行う。

### 本機能の処理概要

コントローラディスパッチャーは、ルーターがマッチングしたルートのアクション（コントローラメソッドまたはクロージャ）を実際に実行する責務を担う。依存性注入によるパラメータ解決と、コントローラミドルウェアの収集を行う。

**業務上の目的・背景**：Laravelのルーティングシステムにおいて、ルートのマッチングと実行は分離されている。コントローラディスパッチャーは、この「実行」部分を担当し、コンテナによる依存性注入、ルートパラメータのコントローラメソッドへのマッピング、コントローラ固有のミドルウェア管理を実現する。これにより、コントローラのテスタビリティと柔軟性が向上する。

**機能の利用シーン**：
- コントローラメソッドの実行
- クロージャルートの実行
- 依存性注入によるパラメータ解決
- コントローラミドルウェアの取得
- リソースコントローラの各アクション実行

**主要な処理内容**：
1. コントローラメソッドの実行（ControllerDispatcher::dispatch メソッド）
2. クロージャの実行（CallableDispatcher::dispatch メソッド）
3. メソッドパラメータの解決（resolveParameters メソッド）
4. 依存性の解決（resolveClassMethodDependencies メソッド）
5. コントローラミドルウェアの取得（getMiddleware メソッド）
6. ミドルウェアのフィルタリング（methodExcludedByOptions メソッド）

**関連システム・外部連携**：
- コンテナ：依存性注入による型ヒント解決
- ルーター：ルートパラメータの提供
- ミドルウェア：コントローラ固有のミドルウェア定義

**権限による制御**：ディスパッチャー自体は権限制御を持たないが、コントローラミドルウェアを通じてアクセス制御を実現。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 全てのコントローラベースの画面で使用 |

## 機能種別

ディスパッチ / 依存性注入 / ミドルウェア管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| route | Route | Yes | ルートインスタンス | - |
| controller | mixed | Yes（ControllerDispatcher） | コントローラインスタンス | - |
| method | string | Yes（ControllerDispatcher） | メソッド名 | - |
| callable | callable | Yes（CallableDispatcher） | 呼び出し可能オブジェクト | - |

### 入力データソース

- ルーター：Route::run()からの呼び出し
- ルートパラメータ：Route::parametersWithoutNulls()

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | mixed | コントローラメソッド/クロージャの戻り値 |
| middleware | array | コントローラのミドルウェア配列 |

### 出力先

- ルーターへの戻り値（レスポンスに変換される）

## 処理フロー

### 処理シーケンス

```
1. ディスパッチ開始
   └─ Route::run() からdispatch呼び出し
2. パラメータ解決
   └─ resolveParameters でルートパラメータと型ヒントを解決
3. メソッド実行
   └─ callActionまたは直接メソッド呼び出し
4. 結果返却
   └─ 戻り値をルーターに返却
```

### フローチャート

```mermaid
flowchart TD
    A[dispatch呼び出し] --> B[resolveParameters]
    B --> C[resolveClassMethodDependencies]
    C --> D[コンテナで依存解決]
    D --> E{callAction存在?}
    E -->|Yes| F[controller->callAction]
    E -->|No| G[controller->method直接呼び出し]
    F --> H[結果返却]
    G --> H
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-20-01 | callAction優先 | callActionメソッドがあれば使用、なければ直接呼び出し | dispatch時 |
| BR-20-02 | nullパラメータ除外 | parametersWithoutNullsでnullパラメータを除外 | resolveParameters時 |
| BR-20-03 | ミドルウェア除外 | only/except指定に基づきミドルウェアをフィルタ | getMiddleware時 |
| BR-20-04 | 型ヒント解決 | コンテナで型ヒントされた依存を自動解決 | resolveClassMethodDependencies時 |

### 計算ロジック

```php
// ミドルウェア除外判定
excludedByOnly = !empty($only) && !in_array($method, $only)
excludedByExcept = !empty($except) && in_array($method, $except)
```

## データベース操作仕様

### 操作別データベース影響一覧

コントローラディスパッチャーはデータベースを操作しない。

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | Dispatcher自体はDB操作なし |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | BindingResolutionException | 依存解決失敗 | コンテナバインディングを確認 |
| - | BadMethodCallException | メソッド未定義 | コントローラのメソッドを確認 |

### リトライ仕様

ディスパッチ処理にリトライ機構はない。

## トランザクション仕様

コントローラディスパッチャーはトランザクションを使用しない。コントローラメソッド内でのトランザクション管理はコントローラの責務。

## パフォーマンス要件

- 依存解決はコンテナのキャッシュを活用
- リフレクションの結果はコンテナレベルでキャッシュ

## セキュリティ考慮事項

- コントローラミドルウェアによるアクセス制御
- 依存性注入は登録済みバインディングのみ解決

## 備考

- ResolvesRouteDependenciesトレイト：依存解決の共通ロジック
- FiltersControllerMiddlewareトレイト：ミドルウェアフィルタリング

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: インターフェースを理解する

まず、ディスパッチャーのインターフェースを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ControllerDispatcherContract.php | `src/Illuminate/Routing/Contracts/ControllerDispatcher.php` | dispatch、getMiddlewareの契約を確認 |
| 1-2 | CallableDispatcherContract.php | `src/Illuminate/Routing/Contracts/CallableDispatcher.php` | dispatchの契約を確認 |

**読解のコツ**: インターフェースを先に理解することで、各ディスパッチャーの責務が明確になる。ControllerDispatcherはdispatchとgetMiddleware、CallableDispatcherはdispatchのみを定義。

#### Step 2: ControllerDispatcherを理解する

コントローラディスパッチャーの実装を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ControllerDispatcher.php | `src/Illuminate/Routing/ControllerDispatcher.php` | トレイト使用（11行目） |
| 2-2 | ControllerDispatcher.php | `src/Illuminate/Routing/ControllerDispatcher.php` | dispatchメソッド（38-47行目） |
| 2-3 | ControllerDispatcher.php | `src/Illuminate/Routing/ControllerDispatcher.php` | getMiddlewareメソッド（71-81行目） |

**主要処理フロー**:
1. **11行目**: `FiltersControllerMiddleware`と`ResolvesRouteDependencies`トレイト使用
2. **38-47行目**: `dispatch` - パラメータ解決後、callActionまたは直接呼び出し
3. **57-62行目**: `resolveParameters` - resolveClassMethodDependenciesに委譲
4. **71-81行目**: `getMiddleware` - コントローラからミドルウェア取得、除外フィルタ適用

#### Step 3: CallableDispatcherを理解する

クロージャディスパッチャーの実装を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | CallableDispatcher.php | `src/Illuminate/Routing/CallableDispatcher.php` | トレイト使用（11行目） |
| 3-2 | CallableDispatcher.php | `src/Illuminate/Routing/CallableDispatcher.php` | dispatchメソッド（37-40行目） |
| 3-3 | CallableDispatcher.php | `src/Illuminate/Routing/CallableDispatcher.php` | resolveParametersメソッド（49-52行目） |

**主要処理フロー**:
- **11行目**: `ResolvesRouteDependencies`トレイト使用
- **37-40行目**: `dispatch` - resolveParameters後にcallable実行
- **49-52行目**: `resolveParameters` - ReflectionFunctionでメソッド情報取得

#### Step 4: トレイトを理解する

共通ロジックを提供するトレイトを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ResolvesRouteDependencies.php | `src/Illuminate/Routing/ResolvesRouteDependencies.php` | resolveClassMethodDependencies、resolveMethodDependenciesを確認 |
| 4-2 | FiltersControllerMiddleware.php | `src/Illuminate/Routing/FiltersControllerMiddleware.php` | methodExcludedByOptionsを確認 |

**主要処理フロー**:
- `resolveClassMethodDependencies` - クラスメソッドの依存解決
- `resolveMethodDependencies` - リフレクション情報からの依存解決
- `methodExcludedByOptions` - only/exceptオプションによるフィルタリング

### プログラム呼び出し階層図

```
Route::run()
    │
    ├─ Route::isControllerAction() => true
    │      │
    │      └─ Route::runController()
    │             │
    │             ├─ Container::make($controller)
    │             │      └─ コントローラインスタンス生成
    │             │
    │             └─ ControllerDispatcher::dispatch($route, $controller, $method)
    │                    │
    │                    ├─ ControllerDispatcher::resolveParameters()
    │                    │      └─ ResolvesRouteDependencies::resolveClassMethodDependencies()
    │                    │             │
    │                    │             ├─ Route::parametersWithoutNulls()
    │                    │             │
    │                    │             └─ Container::call() 相当の依存解決
    │                    │
    │                    └─ $controller->callAction($method, $parameters)
    │                           └─ $controller->{$method}(...$parameters)
    │
    └─ Route::isControllerAction() => false
           │
           └─ Route::runCallable()
                  │
                  └─ CallableDispatcher::dispatch($route, $callable)
                         │
                         ├─ CallableDispatcher::resolveParameters()
                         │      └─ ResolvesRouteDependencies::resolveMethodDependencies()
                         │             └─ new ReflectionFunction($callable)
                         │
                         └─ $callable(...$parameters)
```

### データフロー図

```
[入力]                    [処理]                         [出力]

Route              ───▶  parametersWithoutNulls()  ───▶  ルートパラメータ配列
    │                        │
Controller/Method   ───▶  ReflectionMethod          ───▶  メソッド情報
    │                        │
型ヒント            ───▶  Container::make()         ───▶  依存インスタンス
    │                        │
                         resolveParameters()       ───▶  解決済みパラメータ
    │                        │
                         dispatch()                ───▶  メソッド実行結果

Controller         ───▶  getMiddleware()           ───▶  ミドルウェア名配列
    │                        │
Method             ───▶  methodExcludedByOptions() ───▶  除外判定結果
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ControllerDispatcher.php | `src/Illuminate/Routing/ControllerDispatcher.php` | ソース | コントローラディスパッチャー |
| CallableDispatcher.php | `src/Illuminate/Routing/CallableDispatcher.php` | ソース | クロージャディスパッチャー |
| ControllerDispatcher.php | `src/Illuminate/Routing/Contracts/ControllerDispatcher.php` | インターフェース | コントローラディスパッチャー契約 |
| CallableDispatcher.php | `src/Illuminate/Routing/Contracts/CallableDispatcher.php` | インターフェース | クロージャディスパッチャー契約 |
| ResolvesRouteDependencies.php | `src/Illuminate/Routing/ResolvesRouteDependencies.php` | トレイト | 依存解決ロジック |
| FiltersControllerMiddleware.php | `src/Illuminate/Routing/FiltersControllerMiddleware.php` | トレイト | ミドルウェアフィルタリング |
| Route.php | `src/Illuminate/Routing/Route.php` | ソース | ルートエンティティ |
| Controller.php | `src/Illuminate/Routing/Controller.php` | ソース | 基本コントローラ |
| Container.php | `src/Illuminate/Container/Container.php` | ソース | DIコンテナ |
| RoutingServiceProvider.php | `src/Illuminate/Routing/RoutingServiceProvider.php` | ソース | サービスプロバイダー |
