# 機能設計書 4-HttpClient

## 概要

本ドキュメントは、Symfony HttpClientコンポーネントの機能設計を記述する。HttpClientはHTTPリソースを同期・非同期で取得する機能を提供し、CurlHttpClient、NativeHttpClient等の複数実装を含む。

### 本機能の処理概要

HttpClientコンポーネントは、外部HTTPリソースへのリクエスト送信と応答受信を行うHTTPクライアント機能を提供する。cURL拡張、PHP標準ストリーム、Ampライブラリ等の複数バックエンドに対応し、同期・非同期の両方のリクエスト方式をサポートする。

**業務上の目的・背景**：WebアプリケーションやAPIサービスでは、外部APIとの通信、マイクロサービス間通信、Webhook送信等の外部HTTP通信が不可欠である。HttpClientは統一されたインターフェースで多様な通信要件に対応し、リトライ、キャッシュ、スロットリング等の高度な通信制御機能を提供する。

**機能の利用シーン**：外部REST API呼び出し、マイクロサービス間通信、ファイルダウンロード、Server-Sent Events受信、Webhook送信、テスト用モッククライアント利用、HTTP/2プッシュ対応通信等で利用される。

**主要な処理内容**：
1. HTTPリクエストの送信（GET, POST, PUT, DELETE等全メソッド対応）
2. 同期/非同期レスポンス処理
3. 自動クライアント選択（Curl > Amp > Native）
4. リトライ機能（RetryableHttpClient）
5. HTTPキャッシュ（CachingHttpClient）
6. スロットリング（ThrottlingHttpClient）
7. スコーピング（ScopingHttpClient - ベースURI別オプション適用）
8. トレーシング（TraceableHttpClient - プロファイラー連携）
9. Server-Sent Events対応（EventSourceHttpClient）
10. URIテンプレート展開（UriTemplateHttpClient）
11. PSR-18準拠クライアント（Psr18Client）
12. テスト用モッククライアント（MockHttpClient）

**関連システム・外部連携**：外部HTTPサーバー、Messenger（非同期HTTP処理）、Cache（レスポンスキャッシュ）、Profiler（トレースデータ収集）

**権限による制御**：NoPrivateNetworkHttpClientによりプライベートネットワークへのアクセスを制限可能（SSRF対策）。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 22 | Ajaxリクエストパネル | 補助機能 | HTTPクライアント経由のAjaxリクエスト情報の表示 |
| 29 | HTTPクライアントパネル | 主機能 | HttpClientコンポーネントによるHTTPリクエスト/レスポンスのトレース情報の表示 |

## 機能種別

HTTP通信 / 外部API連携 / 非同期処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| method | string | Yes | HTTPメソッド（GET, POST等） | 有効なHTTPメソッド |
| url | string | Yes | リクエスト先URL | 有効なURL形式 |
| options | array | No | リクエストオプション（headers, body, json, query等） | HttpClientInterface::OPTIONS_DEFAULTS参照 |
| maxHostConnections | int | No | 単一ホストへの最大同時接続数（デフォルト: 6） | 正の整数 |
| maxPendingPushes | int | No | HTTP/2プッシュの最大保留数（デフォルト: 50） | 正の整数 |

### 入力データソース

- アプリケーションコード（サービスとして注入されたHttpClientInterface）
- HttpOptions値オブジェクトによる型安全な設定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| statusCode | int | HTTPレスポンスステータスコード |
| headers | array | レスポンスヘッダー |
| content | string | レスポンスボディ |
| info | array | リクエスト/レスポンスの詳細情報 |

### 出力先

- ResponseInterface実装オブジェクトとして返却（遅延評価）
- レスポンスコンテンツはgetContent()呼び出し時に取得

## 処理フロー

### 処理シーケンス

```
1. HttpClient::create()でクライアントインスタンス生成
   └─ 環境に応じてCurlHttpClient/AmpHttpClient/NativeHttpClientを自動選択
2. request()メソッドでHTTPリクエスト送信
   └─ リクエストオプションの解決・バリデーション
3. レスポンスオブジェクト返却（遅延評価）
   └─ ResponseInterfaceを返却、実際のコンテンツはアクセス時に取得
4. レスポンス処理
   └─ getStatusCode(), getHeaders(), getContent(), toArray()でデータ取得
```

### フローチャート

```mermaid
flowchart TD
    A[HttpClient::create] --> B{cURL拡張あり?}
    B -->|Yes| C{HTTP/2対応?}
    B -->|No| D{Ampあり?}
    C -->|Yes| E[CurlHttpClient]
    C -->|No| D
    D -->|Yes| F[AmpHttpClient]
    D -->|No| G[NativeHttpClient]
    E --> H[request メソッド呼び出し]
    F --> H
    G --> H
    H --> I[ResponseInterface返却]
    I --> J{同期/非同期?}
    J -->|同期| K[getContent/toArray]
    J -->|非同期| L[ストリーミング処理]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 自動クライアント選択 | CurlHttpClient > AmpHttpClient > NativeHttpClientの優先順位で自動選択 | HttpClient::create()使用時 |
| BR-02 | SSRF防止 | NoPrivateNetworkHttpClientはプライベートIPへのリクエストをブロック | NoPrivateNetworkHttpClient使用時 |
| BR-03 | リトライ戦略 | 一時的なエラー（5xx, ネットワークエラー）に対して指数バックオフでリトライ | RetryableHttpClient使用時 |
| BR-04 | スコーピング | ベースURIに一致するリクエストにのみ認証ヘッダー等を付加 | ScopingHttpClient使用時 |
| BR-05 | 遅延評価 | レスポンスオブジェクトはgetContent()等のアクセスまで通信を完了しない場合がある | 非同期クライアント使用時 |

### 計算ロジック

- cURLバージョンチェック：`0x073D00`（curl 7.61）以上でHTTP/2対応と判定（HttpClient.php行47）

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

HttpClientコンポーネントはデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | TransportException | ネットワーク接続エラー | ネットワーク設定確認 |
| - | ClientException | 4xxレスポンス受信時（getContent(throw: true)） | リクエストパラメータ確認 |
| - | ServerException | 5xxレスポンス受信時（getContent(throw: true)） | サーバー側確認 |
| - | RedirectionException | リダイレクトループ等 | リダイレクト設定確認 |
| - | TimeoutException | リクエストタイムアウト | timeout設定値の調整 |

### リトライ仕様

RetryableHttpClientで設定可能。デフォルトは指数バックオフ戦略を使用。

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

トランザクション管理なし。

## パフォーマンス要件

- CurlHttpClientはHTTP/2多重化によるパフォーマンス最適化
- 非同期レスポンスにより並行リクエスト処理が可能
- ThrottlingHttpClientでレート制限を設定可能

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

- **SSRF防止**: NoPrivateNetworkHttpClientでプライベートネットワークへのアクセスを制限
- **TLS/SSL**: cURL/Amphpの証明書検証機能を利用
- **認証情報のスコーピング**: ScopingHttpClientで特定ドメインのみに認証情報を送信

## 備考

- HTTPlugインターフェース互換クライアント（HttplugClient）も提供
- Messenger統合によりHTTPリクエストを非同期メッセージキュー経由で実行可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | HttpOptions.php | `src/Symfony/Component/HttpClient/HttpOptions.php` | リクエストオプションの型安全な値オブジェクト |
| 1-2 | Response/ | `src/Symfony/Component/HttpClient/Response/` | レスポンスオブジェクト群の構造 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | HttpClient.php | `src/Symfony/Component/HttpClient/HttpClient.php` | ファクトリクラス。環境に応じたクライアント自動選択 |

**主要処理フロー**:
1. **31行目**: create()メソッド - 環境検出によるクライアント自動選択
2. **33-50行目**: Amp + cURL条件分岐（cURLバージョンチェック含む）
3. **52-57行目**: cURL単独での選択（Windows環境のCAファイル警告含む）
4. **66-67行目**: フォールバック：NativeHttpClient
5. **72-77行目**: createForBaseUri() - スコーピング付きクライアント生成

#### Step 3: 各クライアント実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | CurlHttpClient.php | `src/Symfony/Component/HttpClient/CurlHttpClient.php` | cURL拡張ベースの実装 |
| 3-2 | NativeHttpClient.php | `src/Symfony/Component/HttpClient/NativeHttpClient.php` | PHPストリームベースの実装 |
| 3-3 | AmpHttpClient.php | `src/Symfony/Component/HttpClient/AmpHttpClient.php` | Amphpベースの非同期実装 |

#### Step 4: デコレーターパターンを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | RetryableHttpClient.php | `src/Symfony/Component/HttpClient/RetryableHttpClient.php` | リトライ機能のデコレーター |
| 4-2 | CachingHttpClient.php | `src/Symfony/Component/HttpClient/CachingHttpClient.php` | キャッシュ機能のデコレーター |
| 4-3 | ThrottlingHttpClient.php | `src/Symfony/Component/HttpClient/ThrottlingHttpClient.php` | スロットリングのデコレーター |
| 4-4 | ScopingHttpClient.php | `src/Symfony/Component/HttpClient/ScopingHttpClient.php` | スコーピングのデコレーター |
| 4-5 | TraceableHttpClient.php | `src/Symfony/Component/HttpClient/TraceableHttpClient.php` | トレース用デコレーター |
| 4-6 | NoPrivateNetworkHttpClient.php | `src/Symfony/Component/HttpClient/NoPrivateNetworkHttpClient.php` | SSRF防止デコレーター |

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

```
HttpClient::create(defaultOptions, maxHostConnections, maxPendingPushes)
    |
    +-- [条件分岐] new CurlHttpClient(defaultOptions, ...)
    |                  or AmpHttpClient(defaultOptions, ...)
    |                  or NativeHttpClient(defaultOptions, ...)
    |
    +-- [デコレーター適用（任意）]
            +-- ScopingHttpClient::forBaseUri(client, baseUri, options)
            +-- RetryableHttpClient(client, strategy, maxRetries)
            +-- CachingHttpClient(client, store)
            +-- ThrottlingHttpClient(client, limiter)
            +-- NoPrivateNetworkHttpClient(client)
            +-- TraceableHttpClient(client)

client->request(method, url, options)
    |
    +-- HttpClientTrait::prepareRequest() [オプション解決]
    +-- [実際のHTTP通信実行]
    +-- ResponseInterface返却
```

### データフロー図

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

method + url + options --->  HttpClientTrait             --->  ResponseInterface
                              ::prepareRequest()                (遅延評価)
                              |
                              v
                     CurlHttpClient/                  --->  実際のHTTP通信
                     AmpHttpClient/
                     NativeHttpClient
                              |
                              v
                     getStatusCode()                  --->  int
                     getHeaders()                     --->  array
                     getContent()                     --->  string
                     toArray()                        --->  array
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| HttpClient.php | `src/Symfony/Component/HttpClient/HttpClient.php` | ソース | ファクトリクラス |
| CurlHttpClient.php | `src/Symfony/Component/HttpClient/CurlHttpClient.php` | ソース | cURLベースHTTPクライアント |
| NativeHttpClient.php | `src/Symfony/Component/HttpClient/NativeHttpClient.php` | ソース | PHPストリームベースHTTPクライアント |
| AmpHttpClient.php | `src/Symfony/Component/HttpClient/AmpHttpClient.php` | ソース | AmpベースHTTPクライアント |
| HttpClientTrait.php | `src/Symfony/Component/HttpClient/HttpClientTrait.php` | ソース | 共通リクエスト準備ロジック |
| HttpOptions.php | `src/Symfony/Component/HttpClient/HttpOptions.php` | ソース | リクエストオプション値オブジェクト |
| RetryableHttpClient.php | `src/Symfony/Component/HttpClient/RetryableHttpClient.php` | ソース | リトライデコレーター |
| CachingHttpClient.php | `src/Symfony/Component/HttpClient/CachingHttpClient.php` | ソース | キャッシュデコレーター |
| ThrottlingHttpClient.php | `src/Symfony/Component/HttpClient/ThrottlingHttpClient.php` | ソース | スロットリングデコレーター |
| ScopingHttpClient.php | `src/Symfony/Component/HttpClient/ScopingHttpClient.php` | ソース | スコーピングデコレーター |
| TraceableHttpClient.php | `src/Symfony/Component/HttpClient/TraceableHttpClient.php` | ソース | トレースデコレーター |
| NoPrivateNetworkHttpClient.php | `src/Symfony/Component/HttpClient/NoPrivateNetworkHttpClient.php` | ソース | SSRF防止デコレーター |
| EventSourceHttpClient.php | `src/Symfony/Component/HttpClient/EventSourceHttpClient.php` | ソース | SSEクライアント |
| UriTemplateHttpClient.php | `src/Symfony/Component/HttpClient/UriTemplateHttpClient.php` | ソース | URIテンプレートクライアント |
| MockHttpClient.php | `src/Symfony/Component/HttpClient/MockHttpClient.php` | ソース | テスト用モッククライアント |
| Psr18Client.php | `src/Symfony/Component/HttpClient/Psr18Client.php` | ソース | PSR-18準拠クライアント |
| HttplugClient.php | `src/Symfony/Component/HttpClient/HttplugClient.php` | ソース | HTTPlug互換クライアント |
| DecoratorTrait.php | `src/Symfony/Component/HttpClient/DecoratorTrait.php` | ソース | デコレーター共通トレイト |
| AsyncDecoratorTrait.php | `src/Symfony/Component/HttpClient/AsyncDecoratorTrait.php` | ソース | 非同期デコレータートレイト |
| Response/ | `src/Symfony/Component/HttpClient/Response/` | ソース | レスポンス実装群 |
| Retry/ | `src/Symfony/Component/HttpClient/Retry/` | ソース | リトライ戦略 |
| Chunk/ | `src/Symfony/Component/HttpClient/Chunk/` | ソース | レスポンスチャンク |
| DataCollector/ | `src/Symfony/Component/HttpClient/DataCollector/` | ソース | プロファイラー用データコレクター |
| DependencyInjection/ | `src/Symfony/Component/HttpClient/DependencyInjection/` | ソース | DI統合 |
| Messenger/ | `src/Symfony/Component/HttpClient/Messenger/` | ソース | Messenger統合 |
