# 機能設計書 19-レスポンスファクトリ

## 概要

本ドキュメントは、Laravel FrameworkのレスポンスファクトリResponseFactory機能の設計を詳細に記述したものである。様々な種類のHTTPレスポンス（HTML、JSON、ファイルダウンロード、ストリーム等）を生成するためのファクトリメソッドを提供する。

### 本機能の処理概要

レスポンスファクトリは、アプリケーションで必要となる様々な形式のHTTPレスポンスを一貫したAPIで生成し、ビューのレンダリング、JSONレスポンス、ファイルダウンロード、ストリーミングレスポンスなど多様な出力形式をサポートする。

**業務上の目的・背景**：Webアプリケーションでは、HTMLページ、JSON API、ファイルダウンロード、リアルタイムストリームなど、様々な形式のレスポンスを返す必要がある。レスポンスファクトリは、これらのレスポンス生成を統一されたインターフェースで提供し、適切なヘッダー設定やコンテンツ整形を自動化する。

**機能の利用シーン**：
- コントローラからのビューレスポンス返却
- APIエンドポイントからのJSONレスポンス
- CSVやExcelファイルのダウンロード
- 画像や動画のインライン表示
- Server-Sent Events（SSE）によるリアルタイム通信
- 大量データのストリーミング出力

**主要な処理内容**：
1. 基本レスポンス生成（make メソッド）
2. ビューレスポンス生成（view メソッド）
3. JSONレスポンス生成（json, jsonp メソッド）
4. ストリーミングレスポンス生成（stream, streamJson, eventStream メソッド）
5. ファイルダウンロード（download, streamDownload メソッド）
6. ファイル表示（file メソッド）
7. リダイレクトレスポンス（redirectTo, redirectToRoute, redirectToAction 等）
8. 空レスポンス（noContent メソッド）

**関連システム・外部連携**：
- ビューファクトリ：ビューのレンダリング
- リダイレクター：リダイレクトレスポンス生成の委譲
- SymfonyResponse：基盤レスポンスクラス

**権限による制御**：レスポンスファクトリ自体は権限制御を持たない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 全画面からのレスポンス生成で使用 |

## 機能種別

HTTPレスポンス / ファクトリ / データ出力

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| content | mixed | No（make時） | レスポンスコンテンツ | - |
| status | int | No | HTTPステータスコード | デフォルト200 |
| headers | array | No | HTTPヘッダー | - |
| view | string/array | Yes（view時） | ビュー名または候補配列 | - |
| data | array | No（view時） | ビューデータ | - |
| options | int | No（json時） | JSONエンコードオプション | - |
| callback | Closure/callable | Yes（stream/eventStream時） | コールバック関数 | - |
| file | SplFileInfo/string | Yes（download/file時） | ファイルパスまたはオブジェクト | ファイル存在 |
| name | string/null | No（download時） | ダウンロードファイル名 | - |
| disposition | string/null | No（download時） | Content-Disposition | attachment/inline |

### 入力データソース

- コントローラ：response()ヘルパー経由の呼び出し
- ビューファクトリ：ビューテンプレート

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| response | Response/JsonResponse/StreamedResponse/BinaryFileResponse/RedirectResponse | 生成されたレスポンス |

### 出力先

- HTTPレスポンス：ブラウザ/APIクライアント

## 処理フロー

### 処理シーケンス

```
1. レスポンス生成要求
   └─ make(), view(), json(), stream() 等の呼び出し
2. コンテンツ準備
   └─ ビューレンダリング、JSON変換、ファイル読み込み等
3. レスポンスオブジェクト生成
   └─ 適切なResponseクラスをインスタンス化
4. ヘッダー設定
   └─ Content-Type、Content-Disposition等
5. レスポンス返却
   └─ 生成したレスポンスを返却
```

### フローチャート

```mermaid
flowchart TD
    A[レスポンス生成要求] --> B{メソッド種別}
    B -->|make| C[Responseインスタンス生成]
    B -->|view| D[ビューレンダリング]
    B -->|json| E[JsonResponseインスタンス生成]
    B -->|stream| F[StreamedResponseインスタンス生成]
    B -->|download| G[BinaryFileResponseインスタンス生成]
    B -->|redirect| H[Redirectorに委譲]
    D --> C
    C --> I[ヘッダー設定]
    E --> I
    F --> I
    G --> I
    H --> I
    I --> J[レスポンス返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-19-01 | noContentステータス | noContentメソッドのデフォルトステータスは204 | noContent()呼び出し時 |
| BR-19-02 | eventStreamヘッダー | Content-Type: text/event-stream、Cache-Control: no-cache、X-Accel-Buffering: no | eventStream()呼び出し時 |
| BR-19-03 | ストリームダウンロード例外ラップ | streamDownloadの例外はStreamedResponseExceptionでラップ | streamDownload()呼び出し時 |
| BR-19-04 | ファイル名フォールバック | 非ASCII文字を含むファイル名はASCII変換したフォールバック名を設定 | download()呼び出し時 |
| BR-19-05 | ジェネレータ対応 | streamメソッドでジェネレータが渡された場合は自動でチャンク出力 | stream()呼び出し時 |

### 計算ロジック

```php
// ASCIIファイル名フォールバック
fallbackName = str_replace('%', '', Str::ascii($name))

// eventStreamのデータフォーマット
echo "event: $event\n";
echo 'data: '.$message;
echo "\n\n";
```

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

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

レスポンスファクトリはデータベースを操作しない。

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | FileNotFoundException | downloadでファイルが存在しない | ファイルパスを確認 |
| - | StreamedResponseException | streamDownloadでコールバック内例外 | コールバック内の処理を確認 |
| - | InvalidArgumentException | 不正なJSONオプション | オプション値を確認 |

### リトライ仕様

レスポンス生成にリトライ機構はない。

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

レスポンスファクトリはトランザクションを使用しない。

## パフォーマンス要件

- ストリーミング：大容量ファイルのメモリ効率的な配信
- チャンク出力：バッファリングの制御（ob_flush, flush）
- X-Accel-Bufferingヘッダー：nginx等のバッファリング無効化

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

- Content-Disposition：ファイル名のエスケープ処理
- streamDownload：例外情報の漏洩防止
- JSONレスポンス：適切なエンコードオプション

## 備考

- Macroableトレイト：カスタムレスポンスメソッドの追加が可能
- Octane対応：ジェネレータ使用時のsetCallback処理
- StreamedEvent：eventStreamでイベント名を指定可能

---

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

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

### 推奨読解順序

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

まず、レスポンスファクトリが保持するデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ResponseFactory.php | `src/Illuminate/Routing/ResponseFactory.php` | プロパティ定義（$view, $redirector）を確認 |

**読解のコツ**: ResponseFactoryは2つの主要プロパティを持つ。`$view`はビューファクトリへの参照、`$redirector`はリダイレクターへの参照である。

#### Step 2: 基本レスポンス生成を理解する

make、view、noContentメソッドを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ResponseFactory.php | `src/Illuminate/Routing/ResponseFactory.php` | makeメソッド（59-62行目） |
| 2-2 | ResponseFactory.php | `src/Illuminate/Routing/ResponseFactory.php` | noContentメソッド（71-74行目） |
| 2-3 | ResponseFactory.php | `src/Illuminate/Routing/ResponseFactory.php` | viewメソッド（85-92行目） |

**主要処理フロー**:
1. **59-62行目**: `make` - new Responseでインスタンス生成
2. **71-74行目**: `noContent` - make('')で空コンテンツ、デフォルト204
3. **85-92行目**: `view` - 配列なら$view->first、それ以外は$view->make

#### Step 3: JSONレスポンス生成を理解する

json、jsonp、streamJsonメソッドを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ResponseFactory.php | `src/Illuminate/Routing/ResponseFactory.php` | jsonメソッド（103-106行目） |
| 3-2 | ResponseFactory.php | `src/Illuminate/Routing/ResponseFactory.php` | jsonpメソッド（118-121行目） |
| 3-3 | ResponseFactory.php | `src/Illuminate/Routing/ResponseFactory.php` | streamJsonメソッド（224-227行目） |

**主要処理フロー**:
- **103-106行目**: `json` - new JsonResponseでインスタンス生成
- **118-121行目**: `jsonp` - jsonを呼び出しsetCallback
- **224-227行目**: `streamJson` - StreamedJsonResponseでストリーム出力

#### Step 4: ストリーミングレスポンスを理解する

stream、eventStream、streamDownloadメソッドを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ResponseFactory.php | `src/Illuminate/Routing/ResponseFactory.php` | eventStreamメソッド（131-184行目） |
| 4-2 | ResponseFactory.php | `src/Illuminate/Routing/ResponseFactory.php` | streamメソッド（194-213行目） |
| 4-3 | ResponseFactory.php | `src/Illuminate/Routing/ResponseFactory.php` | streamDownloadメソッド（240-261行目） |

**主要処理フロー**:
- **131-184行目**: `eventStream` - SSE形式でイベント出力、endStreamWith対応
- **194-213行目**: `stream` - ジェネレータ対応、Octane環境対応
- **240-261行目**: `streamDownload` - 例外をStreamedResponseExceptionでラップ

#### Step 5: ファイルレスポンスを理解する

download、fileメソッドを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | ResponseFactory.php | `src/Illuminate/Routing/ResponseFactory.php` | downloadメソッド（272-281行目） |
| 5-2 | ResponseFactory.php | `src/Illuminate/Routing/ResponseFactory.php` | fallbackNameメソッド（289-292行目） |
| 5-3 | ResponseFactory.php | `src/Illuminate/Routing/ResponseFactory.php` | fileメソッド（301-304行目） |

**主要処理フロー**:
- **272-281行目**: `download` - BinaryFileResponse、Content-Disposition設定
- **289-292行目**: `fallbackName` - ASCII変換、%除去
- **301-304行目**: `file` - BinaryFileResponse（dispositionなし）

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

```
ResponseFactory::view($view, $data, $status, $headers)
    │
    ├─ ViewFactory::first($view, $data)  // 配列の場合
    │      └─ View::render()
    │
    └─ ViewFactory::make($view, $data)   // 文字列の場合
           └─ View::render()
    │
    └─ ResponseFactory::make($renderedView, $status, $headers)
           └─ new Response($content, $status, $headers)

ResponseFactory::eventStream($callback, $headers, $endStreamWith)
    │
    └─ ResponseFactory::stream(...)
           │
           └─ new StreamedResponse(function() use ($callback) {
                  foreach ($callback() as $message) {
                      echo "event: $event\n";
                      echo "data: $message\n\n";
                      ob_flush();
                      flush();
                  }
              }, 200, $headers)

ResponseFactory::download($file, $name, $headers, $disposition)
    │
    ├─ new BinaryFileResponse($file, 200, $headers, true, $disposition)
    │
    └─ BinaryFileResponse::setContentDisposition($disposition, $name, $fallbackName)
```

### データフロー図

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

ビュー名          ───▶  ViewFactory::make()        ───▶  レンダリング済みHTML
    │                        │
                         ResponseFactory::make()    ───▶  Response

データ配列        ───▶  json_encode()              ───▶  JSON文字列
    │                        │
                         new JsonResponse()         ───▶  JsonResponse

コールバック      ───▶  StreamedResponse           ───▶  チャンク出力
    │                        │
                         ob_flush() + flush()       ───▶  バッファフラッシュ

ファイルパス      ───▶  BinaryFileResponse         ───▶  ファイルコンテンツ
    │                        │
ファイル名        ───▶  fallbackName()             ───▶  ASCII変換名
    │                        │
                         setContentDisposition()    ───▶  ヘッダー設定
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ResponseFactory.php | `src/Illuminate/Routing/ResponseFactory.php` | ソース | レスポンスファクトリコア実装 |
| Response.php | `src/Illuminate/Http/Response.php` | ソース | 基本レスポンス |
| JsonResponse.php | `src/Illuminate/Http/JsonResponse.php` | ソース | JSONレスポンス |
| RedirectResponse.php | `src/Illuminate/Http/RedirectResponse.php` | ソース | リダイレクトレスポンス |
| StreamedEvent.php | `src/Illuminate/Http/StreamedEvent.php` | ソース | ストリームイベント |
| StreamedResponseException.php | `src/Illuminate/Routing/Exceptions/StreamedResponseException.php` | ソース | ストリーム例外 |
| ResponseFactoryContract.php | `src/Illuminate/Contracts/Routing/ResponseFactory.php` | インターフェース | ファクトリ契約 |
| Factory.php | `src/Illuminate/Contracts/View/Factory.php` | インターフェース | ビューファクトリ契約 |
| Redirector.php | `src/Illuminate/Routing/Redirector.php` | ソース | リダイレクター |
| RoutingServiceProvider.php | `src/Illuminate/Routing/RoutingServiceProvider.php` | ソース | サービスプロバイダー |
