# 画面設計書 6-429 Too Many Requests

## 概要

本ドキュメントは、Laravel フレームワークにおける HTTP 429 Too Many Requests エラー画面の設計書です。レート制限（Rate Limiting）を超えてリクエストを送信した場合に表示されるエラー画面について記載しています。

### 本画面の処理概要

HTTP 429 Too Many Requests エラー画面は、ユーザーが設定されたレート制限を超えてリクエストを送信した場合に表示される画面です。この画面は、ユーザーに対して一時的にリクエストが制限されていることを通知し、しばらく待ってから再試行することを促す役割を果たします。

**業務上の目的・背景**：Web アプリケーションにおいて、サーバーリソースの保護、DDoS 攻撃の軽減、API の公平な使用を確保するためにレート制限が実装されます。本画面は、レート制限に達したユーザーに対して適切なフィードバックを提供し、いつ再試行できるかの情報を伝えます。これにより、ユーザーは無駄なリトライを避け、システムの安定性が維持されます。また、悪意のある自動化されたリクエストや、意図せず過度なリクエストを送信しているクライアントに対する防御機構としても機能します。

**画面へのアクセス方法**：この画面は直接アクセスするものではなく、以下のような状況で自動的に表示されます。
1. ThrottleRequests ミドルウェアでレート制限に達した場合
2. RateLimiter による制限を超えた場合
3. API エンドポイントへの過度なリクエスト時
4. ログイン試行回数の制限を超えた場合

**主要な操作・処理内容**：
1. エラーコード「429」とメッセージ「Too Many Requests」を画面中央に表示
2. ダークモード対応のスタイリングにより、ユーザーの表示設定に応じた適切な配色で表示
3. レスポンシブデザインにより、デスクトップ・モバイル両方のデバイスで適切に表示

**画面遷移**：
- 遷移元：レート制限を超えた任意のリクエスト
- 遷移先：なし（エラー表示のみ。ユーザーは `Retry-After` ヘッダーで指定された時間を待って再試行可能）

**権限による表示制御**：この画面は権限に関係なく、レート制限に達した場合に全てのユーザーに表示されます。ただし、レート制限の設定は認証済みユーザーと未認証ユーザーで異なる場合があります。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 11 | レートリミッター | 主機能 | リクエスト過多エラー表示（レート制限超過時） |
| 36 | ビューファクトリ | 補助機能 | Blade テンプレートのレンダリング処理 |

## 画面種別

エラー表示画面

## URL/ルーティング

この画面は特定の URL を持ちません。HTTP レスポンスステータスコード 429 が返される際に、例外ハンドラ（`Illuminate\Foundation\Exceptions\Handler`）により自動的にレンダリングされます。

## 入出力項目

### 入力項目

| 項目名 | 型 | 必須 | 説明 |
|--------|------|------|------|
| なし | - | - | この画面は入力項目を持ちません |

### 出力項目（テンプレート変数）

| 項目名 | 型 | 説明 |
|--------|------|------|
| $exception | HttpExceptionInterface | 発生した例外オブジェクト |
| $errors | ViewErrorBag | バリデーションエラーバッグ（空） |

### HTTPレスポンスヘッダー

| ヘッダー名 | 説明 |
|-----------|------|
| Retry-After | 再試行可能になるまでの秒数 |
| X-RateLimit-Limit | 設定されたレート制限値 |
| X-RateLimit-Remaining | 残りのリクエスト回数 |

## 表示項目

| 項目 | 表示内容 | スタイル |
|------|----------|----------|
| エラーコード | 429 | 大きなフォント、右ボーダー付き |
| エラーメッセージ | Too Many Requests | 大文字、トラッキング広め |

## イベント仕様

### 1-画面表示

本画面は静的なエラー表示のみを行い、ユーザーインタラクションのイベントは定義されていません。ユーザーは `Retry-After` ヘッダーで指定された時間を待ってから再試行できます。

## データベース更新仕様

本画面はデータベースへの読み書きを行いません。ただし、レート制限の状態はキャッシュ（Redis、Memcached、ファイルなど）に保存されています。

## メッセージ仕様

| メッセージ種別 | メッセージコード | メッセージ内容 | 表示条件 |
|--------------|----------------|--------------|----------|
| エラー | - | Too Many Requests | 常時表示 |

**多言語対応**：メッセージは `__('Too Many Requests')` ヘルパー関数を使用しており、言語ファイルにより翻訳可能です。

## 例外処理

本画面自体が例外処理の結果として表示されるため、画面内での例外処理は定義されていません。テンプレートのレンダリングに失敗した場合は、Symfony の HtmlErrorRenderer によるフォールバック表示が行われます。

## 備考

- この画面は `minimal.blade.php` レイアウトを継承しています
- レスポンスには `Retry-After` ヘッダーが含まれ、クライアントに再試行可能な時間を通知します
- カスタマイズする場合は、`resources/views/errors/429.blade.php` にファイルを配置することで上書き可能です
- ダークモード対応のスタイリングが含まれています（`prefers-color-scheme: dark` メディアクエリ使用）
- API クライアントの場合は JSON レスポンスが返されることがあります

---

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

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

### 推奨読解順序

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

レート制限の仕組みとエラーレスポンスの構造を理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | TooManyRequestsHttpException.php | `vendor/symfony/http-kernel/Exception/TooManyRequestsHttpException.php` | 429 専用の例外クラス、Retry-After ヘッダーの設定 |
| 1-2 | RateLimiter.php | `src/Illuminate/Cache/RateLimiter.php` | レート制限の状態管理 |

**読解のコツ**: レート制限は RateLimiter クラスで管理され、制限を超えた場合に TooManyRequestsHttpException がスローされます。

#### Step 2: レート制限ミドルウェアを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ThrottleRequests.php | `src/Illuminate/Routing/Middleware/ThrottleRequests.php` | レート制限を適用するミドルウェア |

**主要処理フロー**:
- リクエストごとにレート制限をチェック
- 制限を超えた場合に TooManyRequestsHttpException をスロー
- レスポンスヘッダーに制限情報を追加

#### Step 3: 例外ハンドリングを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Handler.php | `src/Illuminate/Foundation/Exceptions/Handler.php` | 例外ハンドラのメインクラス |

**主要処理フロー**:
1. **行 920-938**: `renderHttpException()` メソッドで HTTP 例外のレンダリングを実行
2. **行 922**: `registerErrorViewPaths()` でエラービューのパスを登録
3. **行 958-968**: `getHttpExceptionView()` でステータスコードに基づくビュー名を決定

#### Step 4: テンプレート継承を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | 429.blade.php | `src/Illuminate/Foundation/Exceptions/views/429.blade.php` | 429 エラー専用テンプレート |
| 4-2 | minimal.blade.php | `src/Illuminate/Foundation/Exceptions/views/minimal.blade.php` | 共通レイアウトテンプレート |

**主要処理フロー**:
- **429.blade.php 行 1**: `@extends('errors::minimal')` で共通レイアウトを継承
- **429.blade.php 行 3-5**: `@section` でタイトル、コード、メッセージを定義

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

```
HTTP リクエスト
    │
    ├─ ThrottleRequests ミドルウェア
    │      │
    │      ├─ RateLimiter::tooManyAttempts()
    │      │      └─ 制限チェック
    │      │
    │      └─ 制限超過時
    │             └─ TooManyRequestsHttpException スロー
    │
    ├─ Handler::render()
    │      │
    │      └─ Handler::prepareResponse()
    │             │
    │             └─ Handler::renderHttpException()
    │                    │
    │                    ├─ Handler::registerErrorViewPaths()
    │                    │
    │                    └─ Handler::getHttpExceptionView()
    │                           └─ view()->exists('errors::429')
    │
    └─ response()->view('errors::429', [...])
           │
           ├─ 429.blade.php
           │      └─ minimal.blade.php（継承）
           │
           └─ HTTP ヘッダー追加
                  └─ Retry-After, X-RateLimit-*
```

### データフロー図

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

HTTP リクエスト      ───▶ ThrottleRequests          ───▶ レート制限チェック
                          │
                          ├─ RateLimiter
                          │      └─ キャッシュで状態管理
                          │
                          ├─ 制限超過
                          │      └─ TooManyRequestsHttpException
                          │
                          ▼
                    Handler::render()
                          │
                          ├─ renderHttpException()
                          │      │
                          │      └─ getHttpExceptionView()
                          │             └─ 'errors::429'
                          │
                          └─ response()->view()   ───▶ HTTP Response
                                 │                      (status: 429)
                                 │                      + Retry-After ヘッダー
                                 └─ Blade レンダリング
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| 429.blade.php | `src/Illuminate/Foundation/Exceptions/views/429.blade.php` | テンプレート | 429 エラー専用のコンテンツ定義 |
| minimal.blade.php | `src/Illuminate/Foundation/Exceptions/views/minimal.blade.php` | テンプレート | エラー画面の共通レイアウト |
| Handler.php | `src/Illuminate/Foundation/Exceptions/Handler.php` | ソース | 例外ハンドリングとビュー選択のロジック |
| RegisterErrorViewPaths.php | `src/Illuminate/Foundation/Exceptions/RegisterErrorViewPaths.php` | ソース | エラービューパスの登録処理 |
| ThrottleRequests.php | `src/Illuminate/Routing/Middleware/ThrottleRequests.php` | ソース | レート制限ミドルウェア |
| RateLimiter.php | `src/Illuminate/Cache/RateLimiter.php` | ソース | レート制限の状態管理 |
