# 機能設計書 25-Serializer

## 概要

本ドキュメントは、Symfony Serializerコンポーネントの機能設計を記述する。このコンポーネントはオブジェクトグラフを含むデータ構造のシリアライズ・デシリアライズ機能を提供し、JSON、XML、CSV等の形式に対応する。

### 本機能の処理概要

**業務上の目的・背景**：Webアプリケーションにおいて、オブジェクトとJSON/XML/CSV等のデータ形式間の変換は頻出する処理である。API応答の生成、外部APIからの応答解析、データのインポート/エクスポート等、多くの場面でシリアライズ/デシリアライズが必要となる。本コンポーネントは統一的なインターフェースでこれらの変換を実現し、正規化（Normalizer）とエンコード（Encoder）の二段階処理により柔軟な変換パイプラインを構築する。

**機能の利用シーン**：REST API応答のJSON/XML生成、APIリクエストボディのオブジェクトへの変換、CSVインポート/エクスポート、キャッシュデータのシリアライズ、メッセージキューのメッセージシリアライズ、DTOオブジェクト間の変換。

**主要な処理内容**：
1. Serializerクラスによるserialize（オブジェクト -> 文字列）とdeserialize（文字列 -> オブジェクト）の統合
2. Normalizerによるオブジェクトと配列間の正規化・非正規化（ObjectNormalizer、ArrayDenormalizer等）
3. Encoderによる配列と文字列間のエンコード・デコード（JsonEncoder、XmlEncoder、CsvEncoder等）
4. Attributeアノテーションによるシリアライズグループ、名前変換、最大深度等のカスタマイズ
5. NameConverterによるプロパティ名の変換（CamelCase <-> snake_case等）
6. キャッシュ機構によるNormalizer/Denormalizerの選択結果のキャッシング

**関連システム・外部連携**：PropertyAccess（プロパティ読み書き）、PropertyInfo（型情報抽出）、TypeInfo（型解析）、Validator（バリデーション統合）、HttpKernel（DataCollector）と連携する。

**権限による制御**：シリアライズグループ（Groups）により、ユーザーの権限に応じて異なるプロパティセットをシリアライズ可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 33 | シリアライザーパネル | 主機能 | Serializerコンポーネントによるシリアライズ/デシリアライズの処理情報の表示 |

## 機能種別

データ変換 / シリアライゼーション

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| data | mixed | Yes | シリアライズ対象のデータ（オブジェクト、配列等） | - |
| format | string | Yes | 出力形式（json, xml, csv等） | エンコーダーがサポートする形式 |
| type | string | Yes（deserialize時） | デシリアライズ先の型名（FQCN） | 存在するクラス名 |
| context | array | No | コンテキストオプション（グループ、最大深度等） | キーに応じたバリデーション |

### 入力データソース

APIリクエストボディ、データベースから取得したオブジェクト、CSVファイル、外部APIレスポンス

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| serialized | string | シリアライズされた文字列（JSON、XML、CSV等） |
| deserialized | mixed | デシリアライズされたオブジェクトまたはデータ |
| normalized | array/scalar | 正規化された配列またはスカラー値 |

### 出力先

HTTPレスポンスボディ、ファイル、メッセージキュー、キャッシュストレージ

## 処理フロー

### 処理シーケンス

```
1. シリアライズ (serialize)
   └─ データ -> Normalizer群で正規化 -> Encoder群でエンコード -> 文字列
2. デシリアライズ (deserialize)
   └─ 文字列 -> Decoder群でデコード -> Denormalizer群で非正規化 -> オブジェクト
3. Normalizer選択
   └─ getSupportedTypes()とsupportsNormalization()でキャッシュ付き選択
4. Encoder選択
   └─ ChainEncoder/ChainDecoderで形式に対応するエンコーダーを選択
```

### フローチャート

```mermaid
flowchart TD
    A[serialize呼び出し] --> B{format対応のEncoder?}
    B -->|No| C[UnsupportedFormatException]
    B -->|Yes| D{needsNormalization?}
    D -->|Yes| E[normalize実行]
    D -->|No| F[encode実行]
    E --> F
    F --> G[文字列返却]

    H[deserialize呼び出し] --> I{format対応のDecoder?}
    I -->|No| J[UnsupportedFormatException]
    I -->|Yes| K[decode実行]
    K --> L[denormalize実行]
    L --> M[オブジェクト返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-25-01 | Normalizer優先順位 | 登録順に最初にsupportsNormalization()がtrueを返すNormalizerが使用される | normalize()時 |
| BR-25-02 | スカラー型パススルー | null、スカラー値（int, bool, float, string）はNormalizerなしでそのまま返却 | normalize()時 |
| BR-25-03 | EMPTY_ARRAY_AS_OBJECT | コンテキストフラグにより空配列をオブジェクト（JSON: {}）として出力 | シリアライズ時 |
| BR-25-04 | COLLECT_DENORMALIZATION_ERRORS | コンテキストフラグにより、デシリアライズエラーを集約してPartialDenormalizationExceptionで返却 | denormalize()時 |
| BR-25-05 | キャッシュ有効 | getSupportedTypes()でisCacheable=trueのNormalizerはsupportsNormalization()結果がキャッシュされる | Normalizer選択時 |

### 計算ロジック

特になし。

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | UnsupportedFormatException | 指定形式に対応するEncoder/Decoderがない | 対応するEncoder/Decoderを登録 |
| - | NotNormalizableValueException | 正規化/非正規化不可能な値 | 適切なNormalizerを登録 |
| - | PartialDenormalizationException | 複数のデシリアライズエラーが発生 | errors配列で詳細を確認 |
| - | LogicException | Normalizerが未登録 | 少なくとも1つのNormalizerを登録 |
| - | InvalidArgumentException | Normalizer/Encoderが適切なインターフェースを実装していない | 正しいインターフェースを実装 |

### リトライ仕様

リトライは不要。

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

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

## パフォーマンス要件

Normalizer/Denormalizerの選択結果はnormalizerCache/denormalizerCacheにキャッシュされ、同一型の再処理を高速化する。getSupportedTypes()でisCacheable=trueの場合、supportsNormalization/supportsDenormalizationの結果もキャッシュされる。

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

- シリアライズグループにより、APIレスポンスに含めるプロパティを制御可能
- デシリアライズ時の型制約により、不正な型のインジェクションを防止
- MaxDepthアノテーションによる無限再帰の防止

## 備考

Serializerコンポーネントはリッチな機能セットを持ち、多数のNormalizerとEncoderが提供されている。パフォーマンスが重要な場合はJsonStreamerコンポーネントの使用も検討できる。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | SerializerInterface.php | `src/Symfony/Component/Serializer/SerializerInterface.php` | serialize/deserializeの契約 |
| 1-2 | NormalizerInterface.php | `src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php` | normalize/supportsNormalization/getSupportedTypesの契約 |
| 1-3 | DenormalizerInterface.php | `src/Symfony/Component/Serializer/Normalizer/DenormalizerInterface.php` | denormalize/supportsDenormalizationの契約 |
| 1-4 | EncoderInterface.php | `src/Symfony/Component/Serializer/Encoder/EncoderInterface.php` | encode/supportsEncodingの契約 |

**読解のコツ**: Serializerは「Normalizer + Encoder」の二段階パイプライン。オブジェクト -> 配列（Normalizer） -> 文字列（Encoder）。逆方向も同様。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Serializer.php | `src/Symfony/Component/Serializer/Serializer.php` | シリアライザーの中核実装 |

**主要処理フロー**:
1. **80-122行目**: コンストラクタでNormalizer/Encoderの初期化。SerializerAwareInterface等のセッター注入
2. **124-135行目**: serialize()でneedsNormalization確認 -> normalize -> encode
3. **137-146行目**: deserialize()でdecode -> denormalize
4. **148-185行目**: normalize()でスカラー/null/iterable/objectの分岐処理。getNormalizer()で適切なNormalizerを選択
5. **191-241行目**: denormalize()でスカラー型チェック、COLLECT_DENORMALIZATION_ERRORSフラグ対応
6. **265-319行目**: getNormalizer()でキャッシュ付きNormalizer選択。getSupportedTypes()の結果でフィルタリング

#### Step 3: Normalizer群を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ObjectNormalizer.php | `src/Symfony/Component/Serializer/Normalizer/ObjectNormalizer.php` | 汎用オブジェクトNormalizer |
| 3-2 | ArrayDenormalizer.php | `src/Symfony/Component/Serializer/Normalizer/ArrayDenormalizer.php` | 配列型のDenormalizer |
| 3-3 | DateTimeNormalizer.php | `src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php` | DateTime型のNormalizer |

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

```
Serializer::serialize()
    |
    +-- supportsEncoding()
    |       +-- ChainEncoder::supportsEncoding()
    |
    +-- ChainEncoder::needsNormalization()
    |
    +-- normalize()
    |       +-- getNormalizer()  [キャッシュ付き]
    |       |       +-- NormalizerInterface::getSupportedTypes()
    |       |       +-- NormalizerInterface::supportsNormalization()
    |       +-- NormalizerInterface::normalize()
    |
    +-- encode()
            +-- ChainEncoder::encode()
                    +-- JsonEncoder::encode() / XmlEncoder::encode() / ...

Serializer::deserialize()
    |
    +-- supportsDecoding()
    +-- decode()
    |       +-- ChainDecoder::decode()
    +-- denormalize()
            +-- getDenormalizer()  [キャッシュ付き]
            +-- DenormalizerInterface::denormalize()
```

### データフロー図

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

Object ----------------> Normalizer::normalize() -------> array
                              |
array ---------------------> Encoder::encode() ----------> string (JSON/XML/CSV)

string (JSON/XML/CSV) --> Decoder::decode() ------------> array
                              |
array ---------------------> Denormalizer::denormalize() > Object
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Serializer.php | `src/Symfony/Component/Serializer/Serializer.php` | ソース | シリアライザー中核実装 |
| SerializerInterface.php | `src/Symfony/Component/Serializer/SerializerInterface.php` | ソース | シリアライザーインターフェース |
| NormalizerInterface.php | `src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php` | ソース | Normalizerインターフェース |
| DenormalizerInterface.php | `src/Symfony/Component/Serializer/Normalizer/DenormalizerInterface.php` | ソース | Denormalizerインターフェース |
| EncoderInterface.php | `src/Symfony/Component/Serializer/Encoder/EncoderInterface.php` | ソース | Encoderインターフェース |
| DecoderInterface.php | `src/Symfony/Component/Serializer/Encoder/DecoderInterface.php` | ソース | Decoderインターフェース |
| ObjectNormalizer.php | `src/Symfony/Component/Serializer/Normalizer/ObjectNormalizer.php` | ソース | 汎用オブジェクトNormalizer |
| JsonEncoder.php | `src/Symfony/Component/Serializer/Encoder/JsonEncoder.php` | ソース | JSONエンコーダー |
| XmlEncoder.php | `src/Symfony/Component/Serializer/Encoder/XmlEncoder.php` | ソース | XMLエンコーダー |
| CsvEncoder.php | `src/Symfony/Component/Serializer/Encoder/CsvEncoder.php` | ソース | CSVエンコーダー |
| ChainEncoder.php | `src/Symfony/Component/Serializer/Encoder/ChainEncoder.php` | ソース | エンコーダーチェーン |
| ChainDecoder.php | `src/Symfony/Component/Serializer/Encoder/ChainDecoder.php` | ソース | デコーダーチェーン |
