# 機能設計書 26-JsonStreamer

## 概要

本ドキュメントは、Symfony JsonStreamerコンポーネントの機能設計を記述する。このコンポーネントはコード生成ベースの高性能JSON読み書きストリーマーを提供し、型情報に基づくJSONの効率的なストリーミング処理を実現する。

### 本機能の処理概要

**業務上の目的・背景**：大量のJSONデータを扱うAPIやバッチ処理において、従来のSerializerコンポーネントではリフレクションベースの処理がパフォーマンスボトルネックとなることがある。JsonStreamerはPHPコードを事前生成し、requireでロードすることで、ランタイムでのリフレクションを排除した高速なJSON処理を実現する。また、ストリーミング対応により、メモリ効率の良い大規模JSON処理が可能。

**機能の利用シーン**：高パフォーマンスが求められるAPI応答のJSON生成、大規模JSONデータのストリーミング読み取り、型安全なJSONデシリアライゼーション、バッチ処理における大量データのJSON変換。

**主要な処理内容**：
1. JsonStreamReader（read）：JSON文字列/ストリームから型付きPHPオブジェクトへの変換
2. JsonStreamWriter（write）：PHPオブジェクトからJSONチャンクのストリーミング出力
3. StreamReaderGenerator/StreamWriterGenerator：型情報に基づくPHPコードの事前生成とキャッシュ
4. PropertyMetadataLoaderチェーン：型解決、DateTime型変換、属性メタデータの段階的ローディング
5. ValueTransformer：DateTime<->String等のカスタム値変換
6. LazyInstantiator：ストリーム入力時の遅延オブジェクト生成

**関連システム・外部連携**：TypeInfo（型情報解析）、JsonPath（JSONパスでのストリーミングサポート）、PropertyInfo/PropertyAccess（プロパティメタデータ）と連携する。

**権限による制御**：直接的な権限制御はない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | （直接的な画面関連なし） | - | バックエンドJSON処理 |

## 機能種別

データ変換 / JSON高性能ストリーミング

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| input | string/resource | Yes（read時） | JSON文字列またはストリームリソース | 有効なJSON |
| data | mixed | Yes（write時） | シリアライズ対象のデータ | 型パラメータと一致 |
| type | Type | Yes | 処理対象の型情報 | TypeInfoのTypeインスタンス |
| options | array | No | オプション（include_null_properties等） | キーに応じた検証 |

### 入力データソース

JSON文字列、ストリームリソース（ファイル、HTTPレスポンスボディ等）、PHPオブジェクト

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| read結果 | mixed | 型付きPHPオブジェクトまたは値 |
| write結果 | Traversable&Stringable | JSONチャンクのイテラブルかつ文字列化可能なオブジェクト |

### 出力先

PHPオブジェクト、JSONチャンクストリーム

## 処理フロー

### 処理シーケンス

```
1. JSON読み取り (read)
   └─ StreamReaderGeneratorで型に対応するPHPコードを生成
   └─ 生成されたコードをrequireで読み込み
   └─ 入力がストリームの場合LazyInstantiator、文字列の場合Instantiatorを使用
   └─ ValueTransformerで値変換適用
2. JSON書き込み (write)
   └─ StreamWriterGeneratorで型に対応するPHPコードを生成
   └─ 生成されたコードをrequireで読み込み
   └─ ジェネレーターでJSONチャンクをyield
   └─ Traversable&Stringableオブジェクトとして返却
```

### フローチャート

```mermaid
flowchart TD
    A[JsonStreamReader::read] --> B[StreamReaderGenerator::generate]
    B --> C{生成コードキャッシュあり?}
    C -->|Yes| D[キャッシュから読み込み]
    C -->|No| E[PHPコード生成+保存]
    D --> F[require パスからcallable取得]
    E --> F
    F --> G{入力がストリーム?}
    G -->|Yes| H[LazyInstantiator使用]
    G -->|No| I[Instantiator使用]
    H --> J[型付きオブジェクト返却]
    I --> J
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-26-01 | コード生成キャッシュ | 生成されたPHPコードはstreamReadersDir/streamWritersDirにキャッシュ | 全ての読み書き処理 |
| BR-26-02 | ストリーム/文字列分岐 | 入力がresourceの場合LazyInstantiator、stringの場合Instantiatorを使用 | read時 |
| BR-26-03 | デフォルトValueTransformer | StringToDateTimeValueTransformer/DateTimeToStringValueTransformerがデフォルト登録 | create()ファクトリ使用時 |
| BR-26-04 | PropertyMetadataLoaderチェーン | Generic -> DateTime -> Attribute -> Base の順でメタデータをロード | コード生成時 |

### 計算ロジック

特になし。

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

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

直接的なデータベース操作は行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | JsonException | 不正なJSON入力 | 有効なJSON文字列/ストリームを入力 |
| - | UnexpectedValueException | 型変換不能 | 入力データが型定義と一致することを確認 |

### リトライ仕様

リトライは不要。

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

直接的なトランザクション管理は行わない。

## パフォーマンス要件

コード生成ベースのアプローチにより、ランタイムでのリフレクションを排除し、高いスループットを実現する。生成コードはファイルシステムにキャッシュされ、初回以降はrequireのみで動作する。ConfigCacheFactoryInterfaceによるキャッシュ無効化の制御が可能。

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

- 生成コードのキャッシュディレクトリのファイルパーミッション管理が重要
- デフォルトのキャッシュディレクトリはsys_get_temp_dir()を使用するため、本番環境ではアプリケーション固有のディレクトリを指定することを推奨

## 備考

JsonStreamerはSymfony 7.2で導入された比較的新しいコンポーネントで、Serializerの高性能代替として位置づけられている。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | StreamReaderInterface.php | `src/Symfony/Component/JsonStreamer/StreamReaderInterface.php` | read()メソッドの契約 |
| 1-2 | StreamWriterInterface.php | `src/Symfony/Component/JsonStreamer/StreamWriterInterface.php` | write()メソッドの契約 |
| 1-3 | PropertyMetadataLoaderInterface.php | `src/Symfony/Component/JsonStreamer/Mapping/PropertyMetadataLoaderInterface.php` | プロパティメタデータのローダーインターフェース |

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | JsonStreamReader.php | `src/Symfony/Component/JsonStreamer/JsonStreamReader.php` | JSON読み取りエントリーポイント |
| 2-2 | JsonStreamWriter.php | `src/Symfony/Component/JsonStreamer/JsonStreamWriter.php` | JSON書き込みエントリーポイント |

**主要処理フロー (JsonStreamReader)**:
1. **53-63行目**: コンストラクタでStreamReaderGenerator、Instantiator、LazyInstantiatorを初期化
2. **65-72行目**: read()で入力のストリーム/文字列判定 -> コード生成 -> 実行
3. **77-115行目**: create()ファクトリでPropertyMetadataLoaderチェーンを構築

**主要処理フロー (JsonStreamWriter)**:
1. **52-60行目**: コンストラクタでStreamWriterGeneratorを初期化
2. **62-96行目**: write()でコード生成 -> 実行 -> Traversable&Stringableオブジェクト返却
3. **101-139行目**: create()ファクトリでPropertyMetadataLoaderチェーンを構築

#### Step 3: コード生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | StreamReaderGenerator.php | `src/Symfony/Component/JsonStreamer/Read/StreamReaderGenerator.php` | 読み取りコード生成器 |
| 3-2 | StreamWriterGenerator.php | `src/Symfony/Component/JsonStreamer/Write/StreamWriterGenerator.php` | 書き込みコード生成器 |

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

```
JsonStreamReader::read()
    |
    +-- StreamReaderGenerator::generate()
    |       +-- PropertyMetadataLoaderChain
    |       +-- PHPコード生成+キャッシュ
    |
    +-- require $path  [生成コード読み込み]
    |
    +-- 生成関数($input, $valueTransformers, $instantiator, $options)
            +-- Instantiator / LazyInstantiator
            +-- ValueTransformerInterface::transform()

JsonStreamWriter::write()
    |
    +-- StreamWriterGenerator::generate()
    +-- require $path
    +-- 生成関数($data, $valueTransformers, $options)
            +-- ValueTransformerInterface::transform()
            +-- yield JSONチャンク
```

### データフロー図

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

JSON string/resource --> JsonStreamReader::read() ------> typed PHP object
                              |
                         StreamReaderGenerator
                              |
                         生成PHPコード (require)

PHP object ------------> JsonStreamWriter::write() -----> Traversable&Stringable
                              |                           (JSONチャンクストリーム)
                         StreamWriterGenerator
                              |
                         生成PHPコード (require)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| JsonStreamReader.php | `src/Symfony/Component/JsonStreamer/JsonStreamReader.php` | ソース | JSON読み取りエントリーポイント |
| JsonStreamWriter.php | `src/Symfony/Component/JsonStreamer/JsonStreamWriter.php` | ソース | JSON書き込みエントリーポイント |
| StreamReaderInterface.php | `src/Symfony/Component/JsonStreamer/StreamReaderInterface.php` | ソース | 読み取りインターフェース |
| StreamWriterInterface.php | `src/Symfony/Component/JsonStreamer/StreamWriterInterface.php` | ソース | 書き込みインターフェース |
| StreamReaderGenerator.php | `src/Symfony/Component/JsonStreamer/Read/StreamReaderGenerator.php` | ソース | 読み取りコード生成器 |
| StreamWriterGenerator.php | `src/Symfony/Component/JsonStreamer/Write/StreamWriterGenerator.php` | ソース | 書き込みコード生成器 |
| Instantiator.php | `src/Symfony/Component/JsonStreamer/Read/Instantiator.php` | ソース | 即時オブジェクト生成 |
| LazyInstantiator.php | `src/Symfony/Component/JsonStreamer/Read/LazyInstantiator.php` | ソース | 遅延オブジェクト生成 |
| PropertyMetadataLoader.php | `src/Symfony/Component/JsonStreamer/Mapping/PropertyMetadataLoader.php` | ソース | ベースメタデータローダー |
| GenericTypePropertyMetadataLoader.php | `src/Symfony/Component/JsonStreamer/Mapping/GenericTypePropertyMetadataLoader.php` | ソース | ジェネリック型対応ローダー |
| ValueTransformerInterface.php | `src/Symfony/Component/JsonStreamer/ValueTransformer/ValueTransformerInterface.php` | ソース | 値変換インターフェース |
| StringToDateTimeValueTransformer.php | `src/Symfony/Component/JsonStreamer/ValueTransformer/StringToDateTimeValueTransformer.php` | ソース | 文字列->DateTime変換 |
| DateTimeToStringValueTransformer.php | `src/Symfony/Component/JsonStreamer/ValueTransformer/DateTimeToStringValueTransformer.php` | ソース | DateTime->文字列変換 |
