# 機能設計書 16-ルーター

## 概要

本ドキュメントは、Laravel Frameworkのルーター（Router）機能の設計を詳細に記述したものである。HTTPリクエストを適切なコントローラやクロージャにディスパッチし、ミドルウェア、モデルバインディング、ルートグループなどの高度なルーティング機能を提供する。

### 本機能の処理概要

ルーターは、Laravelアプリケーションの中核を担うコンポーネントであり、受信したHTTPリクエストのURIとメソッドに基づいて、適切なアクション（コントローラメソッドまたはクロージャ）にリクエストをディスパッチする。

**業務上の目的・背景**：Webアプリケーションにおいて、URLとアプリケーションロジックの対応付けは最も基本的かつ重要な機能である。ルーターは、この対応付けを宣言的に定義し、RESTfulなAPI設計、リソースルーティング、ミドルウェアによる横断的関心事の分離を可能にする。また、名前付きルートやURL生成により、アプリケーション内のリンク管理を容易にする。

**機能の利用シーン**：
- Webページへのルーティング定義
- RESTful APIエンドポイントの定義
- 認証・認可ミドルウェアの適用
- ルートパラメータのモデルバインディング
- APIバージョニングのためのルートプレフィックス
- フォールバックルートによる404処理

**主要な処理内容**：
1. ルートの登録（get, post, put, patch, delete, any, match メソッド）
2. リソースルートの登録（resource, apiResource メソッド）
3. ルートグループの定義（group メソッド）
4. リクエストのディスパッチ（dispatch, dispatchToRoute メソッド）
5. ルートマッチングとパラメータ抽出（findRoute メソッド）
6. ミドルウェアの解決と実行（gatherRouteMiddleware, resolveMiddleware メソッド）
7. モデルバインディング（substituteBindings, substituteImplicitBindings メソッド）

**関連システム・外部連携**：
- コンテナ：依存性注入とコントローラの解決
- イベント：ルーティングイベントの発行
- パイプライン：ミドルウェアスタックの実行

**権限による制御**：ルーター自体は権限制御を持たないが、ミドルウェア（auth, can等）を通じてルート単位での認証・認可を実現。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | ホーム | 主画面 | トップページルーティング |
| 2 | ログイン | 主画面 | 認証ルーティング |
| 3 | ダッシュボード | 主画面 | 認証後画面ルーティング |
| 4 | 一覧画面 | 主画面 | リソースindex |
| 5 | 詳細画面 | 主画面 | リソースshow |
| 6 | 429 Too Many Requests | エラー | レート制限エラー |
| 7 | 404 Not Found | エラー | ルート未マッチ |

## 機能種別

ルーティング / リクエスト処理 / ミドルウェア管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| uri | string | Yes | ルートURI（パラメータ含む） | - |
| action | array/string/Closure/null | No | アクション定義 | - |
| methods | array/string | Yes（match時） | HTTPメソッド | GET/POST/PUT/PATCH/DELETE/OPTIONS/HEAD |
| attributes | array | Yes（group時） | グループ属性 | - |
| name | string | Yes（resource時） | リソース名 | - |
| controller | string | Yes（resource時） | コントローラクラス | 存在するクラス |

### ルートパラメータ

| パラメータ | 記法 | 説明 |
|-----------|-----|------|
| 必須パラメータ | {id} | URIに必ず含まれる |
| オプショナル | {id?} | 省略可能 |
| 正規表現制約 | where('id', '[0-9]+') | パターンマッチ |

### 入力データソース

- routes/web.php：Webルート定義
- routes/api.php：APIルート定義
- HTTPリクエスト：ディスパッチ対象

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| response | Response | HTTPレスポンス |
| route | Route | マッチしたルート |
| parameters | array | 抽出されたパラメータ |

### 出力先

- HTTPレスポンス：ブラウザ/APIクライアント
- イベント：Routing、RouteMatched、PreparingResponse、ResponsePrepared

## 処理フロー

### 処理シーケンス

```
1. リクエスト受信
   └─ Kernelからdispatch($request)呼び出し
2. ルートマッチング
   └─ findRoute でRouteCollectionからマッチ
3. Routingイベント発行
   └─ マッチング前にRoutingイベント
4. RouteMatchedイベント発行
   └─ マッチ後にRouteMatchedイベント
5. ミドルウェア収集
   └─ gatherRouteMiddleware でミドルウェア解決
6. ミドルウェアパイプライン実行
   └─ Pipelineでミドルウェアを順次実行
7. ルート実行
   └─ Route::run() でアクション実行
8. レスポンス準備
   └─ prepareResponse でSymfonyResponse変換
```

### フローチャート

```mermaid
flowchart TD
    A[HTTPリクエスト] --> B[dispatch]
    B --> C[findRoute]
    C --> D{ルートマッチ?}
    D -->|No| E[NotFoundHttpException]
    D -->|Yes| F[RouteMatchedイベント]
    F --> G[gatherRouteMiddleware]
    G --> H[Pipeline through middleware]
    H --> I[Route::run]
    I --> J{コントローラ?}
    J -->|Yes| K[ControllerDispatcher]
    J -->|No| L[CallableDispatcher]
    K --> M[prepareResponse]
    L --> M
    M --> N[レスポンス返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-16-01 | HTTPメソッド | GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONSをサポート | 全ルート |
| BR-16-02 | GETとHEAD | getメソッドはHEADも自動登録 | get()呼び出し時 |
| BR-16-03 | ミドルウェア優先順位 | middlewarePriorityに基づきソート | resolveMiddleware時 |
| BR-16-04 | 名前空間継承 | グループの名前空間は子ルートに継承 | group内ルート登録時 |
| BR-16-05 | プレフィックス結合 | グループプレフィックスは結合される | group内ルート登録時 |
| BR-16-06 | 暗黙的バインディング | 型ヒントからEloquentモデルを自動解決 | substituteImplicitBindings |

### 計算ロジック

```php
// URIプレフィックスの結合
fullUri = trim(groupPrefix.'/'.$uri, '/') ?: '/'

// ミドルウェアのソート
sortedMiddleware = SortedMiddleware($priority, $middlewares)

// レスポンス変換
if ($response instanceof Responsable) {
    $response = $response->toResponse($request);
}
```

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

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

ルーター自体はデータベースを操作しない。モデルバインディング時にEloquentクエリが発行される。

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 404 | NotFoundHttpException | ルートが見つからない | フォールバックルートを定義 |
| 405 | MethodNotAllowedHttpException | HTTPメソッドが許可されていない | 正しいメソッドを使用 |
| 404 | ModelNotFoundException | モデルバインディングで見つからない | nullableバインディングを使用 |

### リトライ仕様

ルーティング処理にリトライ機構はない。

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

ルーター自体はトランザクションを使用しない。

## パフォーマンス要件

- ルートキャッシュ：route:cacheでコンパイル済みルートを使用
- CompiledRouteCollection：最適化されたルートマッチング
- ミドルウェア重複排除：uniqueMiddlewareで重複を除去

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

- CSRF保護：webミドルウェアグループでVerifyCsrfTokenを適用
- 認証・認可：auth、canミドルウェアでアクセス制御
- レート制限：throttleミドルウェアで流量制御

## 備考

- Macroableトレイト：カスタムルーティングメソッドの追加が可能
- __callマジックメソッド：RouteRegistrarへの委譲

---

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

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

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、ルーターが保持するデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Router.php | `src/Illuminate/Routing/Router.php` | プロパティ定義（$events, $container, $routes, $current）を確認 |
| 1-2 | Router.php | `src/Illuminate/Routing/Router.php` | ミドルウェア関連プロパティ（$middleware, $middlewareGroups, $middlewarePriority） |
| 1-3 | Router.php | `src/Illuminate/Routing/Router.php` | バインダー関連プロパティ（$binders, $patterns） |

**読解のコツ**: Routerは多数のプロパティを持つ。`$routes`はRouteCollection、`$current`は現在マッチしたRoute、`$middleware`はエイリアス定義、`$middlewareGroups`はグループ定義、`$binders`はカスタムバインダーのコレクションである。

#### Step 2: ルート登録を理解する

ルート定義のエントリーポイントを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Router.php | `src/Illuminate/Routing/Router.php` | HTTPメソッドショートカット（get, post, put, patch, delete）158-221行目 |
| 2-2 | Router.php | `src/Illuminate/Routing/Router.php` | addRouteメソッド（554-557行目） |
| 2-3 | Router.php | `src/Illuminate/Routing/Router.php` | createRouteメソッド（567-590行目） |

**主要処理フロー**:
1. **158-161行目**: `get` - GET/HEADの両メソッドでルート登録
2. **306-309行目**: `match` - 指定メソッドでルート登録
3. **554-557行目**: `addRoute` - RouteCollectionに追加
4. **567-590行目**: `createRoute` - Routeインスタンス生成、グループ属性マージ

#### Step 3: ディスパッチ処理を理解する

リクエストディスパッチのフローを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Router.php | `src/Illuminate/Routing/Router.php` | dispatchメソッド（749-754行目） |
| 3-2 | Router.php | `src/Illuminate/Routing/Router.php` | dispatchToRouteメソッド（762-765行目） |
| 3-3 | Router.php | `src/Illuminate/Routing/Router.php` | findRouteメソッド（773-784行目） |
| 3-4 | Router.php | `src/Illuminate/Routing/Router.php` | runRouteメソッド（793-802行目） |

**主要処理フロー**:
- **749-754行目**: `dispatch` - currentRequestを保存しdispatchToRoute呼び出し
- **773-784行目**: `findRoute` - Routingイベント発行、RouteCollectionでマッチング
- **811-824行目**: `runRouteWithinStack` - Pipelineでミドルウェア実行後にRoute::run()

#### Step 4: ミドルウェア処理を理解する

ミドルウェアの解決と実行を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Router.php | `src/Illuminate/Routing/Router.php` | gatherRouteMiddlewareメソッド（832-835行目） |
| 4-2 | Router.php | `src/Illuminate/Routing/Router.php` | resolveMiddlewareメソッド（844-882行目） |
| 4-3 | Router.php | `src/Illuminate/Routing/Router.php` | sortMiddlewareメソッド（890-893行目） |

**主要処理フロー**:
- **832-835行目**: `gatherRouteMiddleware` - ルートからミドルウェア名収集、除外処理適用
- **844-882行目**: `resolveMiddleware` - エイリアス解決、グループ展開、サブクラスチェック
- **890-893行目**: `sortMiddleware` - middlewarePriorityに基づくソート

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

```
Router::dispatch($request)
    │
    ├─ Router::dispatchToRoute($request)
    │      │
    │      ├─ Router::findRoute($request)
    │      │      ├─ Events::dispatch(Routing)
    │      │      ├─ RouteCollection::match($request)
    │      │      └─ Container::instance(Route::class, $route)
    │      │
    │      └─ Router::runRoute($request, $route)
    │             │
    │             ├─ Events::dispatch(RouteMatched)
    │             │
    │             ├─ Router::runRouteWithinStack($route, $request)
    │             │      │
    │             │      ├─ Router::gatherRouteMiddleware($route)
    │             │      │      ├─ Route::gatherMiddleware()
    │             │      │      └─ Router::resolveMiddleware()
    │             │      │
    │             │      └─ Pipeline::through($middleware)->then(...)
    │             │             └─ Route::run()
    │             │                    ├─ ControllerDispatcher::dispatch()
    │             │                    └─ CallableDispatcher::dispatch()
    │             │
    │             └─ Router::prepareResponse($request, $response)
    │                    └─ Router::toResponse($request, $response)
    │
    └─ return Response
```

### データフロー図

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

HTTPリクエスト     ───▶  dispatch()                ───▶  HTTPレスポンス
    │                        │
URI + Method       ───▶  RouteCollection::match()  ───▶  Routeインスタンス
    │                        │
Route              ───▶  gatherRouteMiddleware()   ───▶  ミドルウェア配列
    │                        │
Request            ───▶  Pipeline::through()       ───▶  修正済みRequest
    │                        │
Route              ───▶  Route::run()              ───▶  mixed（生のレスポンス）
    │                        │
mixed              ───▶  prepareResponse()         ───▶  Responseインスタンス
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Router.php | `src/Illuminate/Routing/Router.php` | ソース | ルーターコア実装 |
| Route.php | `src/Illuminate/Routing/Route.php` | ソース | ルートエンティティ |
| RouteCollection.php | `src/Illuminate/Routing/RouteCollection.php` | ソース | ルートコレクション |
| CompiledRouteCollection.php | `src/Illuminate/Routing/CompiledRouteCollection.php` | ソース | コンパイル済みルート |
| RouteGroup.php | `src/Illuminate/Routing/RouteGroup.php` | ソース | グループ属性マージ |
| RouteRegistrar.php | `src/Illuminate/Routing/RouteRegistrar.php` | ソース | Fluent API |
| ResourceRegistrar.php | `src/Illuminate/Routing/ResourceRegistrar.php` | ソース | リソースルート |
| ControllerDispatcher.php | `src/Illuminate/Routing/ControllerDispatcher.php` | ソース | コントローラ実行 |
| CallableDispatcher.php | `src/Illuminate/Routing/CallableDispatcher.php` | ソース | クロージャ実行 |
| Pipeline.php | `src/Illuminate/Pipeline/Pipeline.php` | ソース | ミドルウェアパイプライン |
| MiddlewareNameResolver.php | `src/Illuminate/Routing/MiddlewareNameResolver.php` | ソース | ミドルウェア解決 |
| SortedMiddleware.php | `src/Illuminate/Routing/SortedMiddleware.php` | ソース | ミドルウェアソート |
| ImplicitRouteBinding.php | `src/Illuminate/Routing/ImplicitRouteBinding.php` | ソース | 暗黙的バインディング |
| RoutingServiceProvider.php | `src/Illuminate/Routing/RoutingServiceProvider.php` | ソース | サービスプロバイダー |
