# 第12章　ゲートウェイAPIの設計

> **ナビゲーション**
>
> * 前の章: [第11章　ルーティング設計](/ja/solutions/part5-integration/ch11-routing.md)
> * 次の章: [第13章　APIdogとグランドデザインの接点](/ja/solutions/part6-apidog/ch13-apidog-overview.md)

***

![ゲートウェイAPIの統合設計：RESTful原則から監視アーキテクチャまで——統一エンドポイント・ジョブ管理・監視のベストプラクティス](/files/UImR5LlGTXhxSEe6z3gi)

前章までで「なぜゲートウェイが必要か」「どうルーティングするか」を学びました。この章では、ゲートウェイがクライアントに対して公開する「統一API」の具体的な設計を見ていきます。実際のリクエスト・レスポンスのJSON例を通じて、設計の考え方を身につけましょう。

![ゲートウェイAPIは「RESTfulな統一リソース」「非同期処理」「リアルタイム監視」の3本柱で構築する——統一インターフェース・最適な処理フロー・堅牢な運用監視](/files/iS0fRRbhf89xUPERLx6d)

***

## 12.1 統一エンドポイントの設計方針

### RESTful設計原則

ゲートウェイAPIは\*\*REST（Representational State Transfer）\*\*という設計スタイルに従います。RESTの核心は「**リソース指向**」——扱う対象（翻訳・ジョブ・ベンダーなど）を「リソース」として捉え、URLでその場所を表現します。

重要な原則：

| 原則             | 良い例                  | 悪い例                               |
| -------------- | -------------------- | --------------------------------- |
| URLは名詞（リソース名）  | `/v1/translate`      | `/v1/doTranslate`                 |
| 操作はHTTPメソッドで表現 | `POST /v1/translate` | `GET /v1/translate?action=create` |
| 複数形を使う         | `/v1/vendors`        | `/v1/vendor`                      |

![APIは操作（動詞）ではなく扱う対象（名詞・複数形）をリソースとしてURLで表現する——原則1:URLは名詞・原則2:操作はHTTPメソッド・原則3:リソース群は複数形の正誤パターン比較](/files/BRMiA182S7oe1Hfoya3g)

### バージョニング方針

URLに `/v1/` を含めることでAPIのバージョンを明示します。将来仕様を変更する際は `/v2/` として提供し、既存の `/v1/` との後方互換性を維持します。クライアント側が準備できてから移行できるため、急な変更による障害を防げます。

### 認証設計

ゲートウェイへのアクセスには2段階の認証を組み合わせます。

```
① API Key（長期的な識別子）
   ヘッダー: X-API-Key: ak_prod_xxxxxxxxxxxxxxxx
   
② JWT（短期的な認証トークン）
   ヘッダー: Authorization: Bearer eyJhbGciOiJSUzI1NiJ9...
```

API Keyは「誰のアカウントか」を識別し、JWTは「今この操作を行う権限があるか」を確認します。2つを組み合わせることでセキュリティを高めます。

![バージョン明記による後方互換性の担保と2段階認証による安全なアクセスを実現する——/v1/→/v2/のバージョニング方針とAPI Key（アカウント識別）+JWT（操作権限確認）の2段階認証フロー](/files/nSWQV79LzAsp3oirmtLx)

***

## 12.2 コアエンドポイント一覧と仕様

### エンドポイント一覧

```
POST   /v1/translate              # 同期翻訳（短文）
POST   /v1/translate/jobs         # 非同期翻訳（長文・ドキュメント）
GET    /v1/translate/jobs/{id}    # ジョブ状態確認
DELETE /v1/translate/jobs/{id}    # ジョブキャンセル

POST   /v1/transcribe             # 音声認識
POST   /v1/synthesize             # 音声合成

GET    /v1/vendors                # 利用可能ベンダー一覧
GET    /v1/vendors/{id}/health    # ベンダー死活監視

GET    /v1/usage                  # コスト・使用量集計
GET    /v1/usage/breakdown        # ベンダー別・サービス別内訳
```

![ゲートウェイは「翻訳」「音声処理」「管理・監視」の3つのカテゴリでコアリソースを提供する——カテゴリA:翻訳（同期・非同期・状態確認）・カテゴリB:音声（STT/TTS）・カテゴリC:管理監視（ベンダー/使用量）](/files/NxDl2350YCntOFByRQ3I)

***

### POST /v1/translate（同期翻訳）

短いテキスト（目安として5,000文字以下）をリアルタイムで翻訳します。リクエストを送ると数秒以内に翻訳結果が返ってきます。

![データ量と処理特性に応じ数秒で返す「同期」とジョブIDで管理する「非同期」を明確に使い分ける——同期:短いテキスト・リアルタイム処理・直接返却 vs 非同期:大量テキスト・ジョブキュー・ジョブIDのみ即時返却](/files/AjcDEo3w4Ci4DwABvOKg)

**リクエスト例：**

```json
POST /v1/translate
Content-Type: application/json
X-API-Key: ak_prod_xxxxxxxxxxxxxxxx

{
  "text": "The patient should take one tablet twice daily.",
  "source_lang": "en",
  "target_lang": "ja",
  "domain": "medical",
  "quality_tier": "mt",
  "preferred_vendor": null
}
```

**レスポンス例（成功）：**

```json
{
  "request_id": "req_20260411_abc123",
  "status": "completed",
  "translated_text": "患者は1日2回、1錠服用してください。",
  "source_lang": "en",
  "target_lang": "ja",
  "vendor_used": "aws_translate",
  "character_count": 46,
  "cost_usd": 0.000184,
  "latency_ms": 312,
  "cached": false
}
```

***

### POST /v1/translate/jobs（非同期翻訳）

大量テキストやドキュメントファイルの翻訳に使います。リクエストはすぐに受け付けられ（ジョブIDが返される）、処理は非同期で行われます。

**リクエスト例：**

```json
POST /v1/translate/jobs
Content-Type: application/json

{
  "source_document_url": "https://storage.example.com/docs/contract_en.pdf",
  "source_lang": "en",
  "target_lang": "ja",
  "domain": "legal",
  "quality_tier": "expert_in_the_loop",
  "webhook_url": "https://app.example.com/webhooks/translation-complete",
  "callback_metadata": {"order_id": "ORD-9999"}
}
```

**レスポンス例（受付完了）：**

```json
{
  "job_id": "job_20260411_xyz789",
  "status": "queued",
  "estimated_completion": "2026-04-11T12:00:00Z",
  "created_at": "2026-04-11T09:30:00Z"
}
```

![非同期処理の完了確認は非効率なポーリングではなくWebhookによるプッシュ通知で行う——Step1:リクエスト受付→Step2:バックグラウンド処理→Step3:処理完了→Step4:Webhook通知（GatewayからクライアントへPush）](/files/QpTop2IEa91HfqrNFkFx)

***

### GET /v1/translate/jobs/{id}（ジョブ状態確認）

非同期ジョブの処理状況を確認します。

**レスポンス例（処理完了）：**

```json
{
  "job_id": "job_20260411_xyz789",
  "status": "completed",
  "result_url": "https://storage.example.com/results/contract_ja.pdf",
  "vendor_used": "lsp_api_primary",
  "page_count": 12,
  "cost_usd": 48.00,
  "completed_at": "2026-04-11T11:52:33Z"
}
```

`status` の取りうる値：`queued`（待機中）/ `processing`（処理中）/ `completed`（完了）/ `failed`（失敗）/ `cancelled`（キャンセル済み）

***

### POST /v1/transcribe（音声認識）

音声ファイルをテキストに変換します（Speech-to-Text）。

**リクエスト例：**

```json
POST /v1/transcribe
Content-Type: application/json

{
  "audio_url": "https://storage.example.com/audio/meeting_recording.mp3",
  "language": "ja",
  "domain": "general",
  "enable_timestamps": true
}
```

**レスポンス例：**

```json
{
  "request_id": "req_20260411_trans001",
  "status": "completed",
  "transcript": "本日の会議を始めます。まず先週の議事録を確認します。",
  "segments": [
    {"start_ms": 0,    "end_ms": 3200, "text": "本日の会議を始めます。"},
    {"start_ms": 3300, "end_ms": 6800, "text": "まず先週の議事録を確認します。"}
  ],
  "vendor_used": "google_speech",
  "duration_seconds": 7.1,
  "cost_usd": 0.0071
}
```

***

### POST /v1/synthesize（音声合成）

テキストを音声に変換します（Text-to-Speech）。

**リクエスト例：**

```json
POST /v1/synthesize
Content-Type: application/json

{
  "text": "ご予約を承りました。当日のご来店をお待ちしております。",
  "language": "ja",
  "voice": "female_standard",
  "format": "mp3",
  "speed": 1.0
}
```

**レスポンス例：**

```json
{
  "request_id": "req_20260411_synth001",
  "status": "completed",
  "audio_url": "https://storage.gateway.com/audio/output_req001.mp3",
  "duration_seconds": 4.2,
  "vendor_used": "aws_polly",
  "cost_usd": 0.000016
}
```

![音声認識と音声合成は入力と出力が完全に対称となるデータ変換リソースとして設計する——STT:音声ファイル入力→テキスト出力（POST /v1/transcribe）・TTS:テキスト入力→音声ファイル出力（POST /v1/synthesize）](/files/SuCuzmFD33uVLsn4TgCh)

***

### GET /v1/vendors（ベンダー一覧）

現在設定・有効化されているベンダーの一覧と対応サービスを返します。

**レスポンス例：**

```json
{
  "vendors": [
    {
      "id": "deepl",
      "name": "DeepL",
      "services": ["translate"],
      "supported_lang_pairs": 31,
      "status": "healthy"
    },
    {
      "id": "google_translate",
      "name": "Google Cloud Translation",
      "services": ["translate"],
      "supported_lang_pairs": 10100,
      "status": "healthy"
    },
    {
      "id": "aws_translate",
      "name": "Amazon Translate",
      "services": ["translate"],
      "supported_lang_pairs": 7140,
      "status": "degraded"
    }
  ]
}
```

***

### GET /v1/vendors/{id}/health（ベンダー死活監視）

特定ベンダーのリアルタイム稼働状況を確認します。

**レスポンス例：**

```json
{
  "vendor_id": "deepl",
  "status": "healthy",
  "last_check": "2026-04-11T09:29:50Z",
  "response_time_ms": 187,
  "error_rate_1h": 0.002,
  "circuit_breaker_state": "closed"
}
```

***

### GET /v1/usage（使用量集計）

指定期間の総コスト・総文字数などを返します。

**リクエスト例：**

```
GET /v1/usage?from=2026-04-01&to=2026-04-11
```

**レスポンス例：**

```json
{
  "period": {"from": "2026-04-01", "to": "2026-04-11"},
  "total_requests": 45823,
  "total_characters": 12840000,
  "total_cost_usd": 512.34,
  "budget_limit_usd": 5000.00,
  "budget_used_percent": 10.2
}
```

***

### GET /v1/usage/breakdown（内訳）

ベンダー別・サービス別のコスト内訳を返します。

**レスポンス例：**

```json
{
  "by_vendor": [
    {"vendor": "deepl",            "cost_usd": 310.20, "characters": 7800000},
    {"vendor": "google_translate", "cost_usd": 152.14, "characters": 3800000},
    {"vendor": "aws_translate",    "cost_usd":  50.00, "characters": 1240000}
  ],
  "by_service": [
    {"service": "translate",   "cost_usd": 490.00},
    {"service": "transcribe",  "cost_usd":  18.00},
    {"service": "synthesize",  "cost_usd":   4.34}
  ]
}
```

***

## 12.3 監視・集計の設計

### ベンダー死活監視の仕組み

ゲートウェイは定期的に（例：30秒ごと）各ベンダーへ軽量なテストリクエストを送り、応答時間とエラーの有無を記録します。この仕組みを\*\*ヘルスチェック（Health Check）\*\*と呼びます。結果は前節の `GET /v1/vendors/{id}/health` で確認できます。

ヘルスチェックの判定基準の例：

| 状態              | 条件                          |
| --------------- | --------------------------- |
| `healthy`（正常）   | 応答時間 < 2秒、エラー率 < 1%         |
| `degraded`（低下）  | 応答時間 2〜5秒、またはエラー率 1〜5%      |
| `unhealthy`（異常） | 応答なし、または応答時間 > 5秒、エラー率 > 5% |

![30秒ごとのテストリクエストにより応答時間とエラー率からベンダーの健康状態を3段階で判定する——正常(healthy):応答<2秒&エラー率<1%・低下(degraded):応答2〜5秒またはエラー率1〜5%・異常(unhealthy):応答なしまたは応答>5秒またはエラー率>5%](/files/YVldFkuuREv8FljqnCUR)

### 使用量ダッシュボードのデータモデル

使用量データは時系列で蓄積します。最低限必要なフィールドを示します。

```json
{
  "timestamp": "2026-04-11T09:23:45Z",
  "request_id": "req_20260411_abc123",
  "vendor": "deepl",
  "service": "translate",
  "source_lang": "en",
  "target_lang": "ja",
  "domain": "medical",
  "quality_tier": "mt",
  "character_count": 46,
  "cost_usd": 0.000184,
  "latency_ms": 312,
  "status": "success",
  "fallback_used": false
}
```

このデータを集計することで、ダッシュボードに「今月のコスト推移」「ベンダー別利用割合」「エラー率の推移」などを表示できます。

### Webhookによるジョブ完了通知

非同期ジョブ（長文翻訳など）が完了したとき、クライアントがジョブIDで繰り返し問い合わせる（ポーリング）のは非効率です。**Webhook**とは「完了したらこちらのURLへ通知してください」とあらかじめ登録しておく仕組みです。

ゲートウェイがクライアントのWebhook URLへ送るペイロード例：

```json
POST https://app.example.com/webhooks/translation-complete
Content-Type: application/json

{
  "event": "job.completed",
  "job_id": "job_20260411_xyz789",
  "status": "completed",
  "result_url": "https://storage.gateway.com/results/contract_ja.pdf",
  "completed_at": "2026-04-11T11:52:33Z",
  "metadata": {"order_id": "ORD-9999"}
}
```

リクエスト時に渡した `callback_metadata` がそのまま返ってくるため、クライアント側で「どの注文の翻訳が完了したか」をすぐに紐付けられます。

### エラーログの構造化と分析

エラーが起きたとき、原因を素早く特定できるよう構造化されたログを記録します。

```json
{
  "timestamp": "2026-04-11T09:25:01Z",
  "level": "error",
  "request_id": "req_20260411_err456",
  "vendor": "deepl",
  "error_code": "VENDOR_TIMEOUT",
  "http_status": 504,
  "message": "DeepL API did not respond within 3000ms",
  "fallback_triggered": true,
  "fallback_vendor": "google_translate",
  "fallback_result": "success"
}
```

構造化ログ（キーと値のペアで記録したログ）は、ログ分析ツール（Datadog、CloudWatch、ELKスタックなど）で集計・検索しやすくなります。「先週のDeepLのタイムアウト件数」「フォールバック率が高い言語ペアはどれか」といった問いに即座に答えられる体制が整います。

![構造化ログと時系列データの蓄積により高度なダッシュボード分析と迅速なトラブルシューティングを実現する——Data Pipeline（/v1/usage, /breakdown）→データ処理・蓄積→使用量ダッシュボード・構造化エラーログ分析](/files/CFRTiTZDkC4yD3EHZpe0)

***

Part5ではゲートウェイの概念・ルーティング・API設計という統合設計の核心を学びました。次のPart6では、これらの設計を実際にドキュメント化・テストするためのツールとして**Apidog**を取り上げます。

![設計したAPI仕様を実装・運用可能な形にするためApidogを用いたドキュメント化とテストへ移行する——Step1:統合設計仕様のドキュメント化（Apidogへのインポート）・Step2:モックサーバーによるクライアント開発の前倒し・Step3:エンドポイントの自動テスト構築](/files/HUzchjYsDqdI4RqLTLLr)

***

→ [第13章 APIdogとグランドデザインの接点](/ja/solutions/part6-apidog/ch13-apidog-overview.md)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://translationlab.gitbook.io/ja/solutions/part5-integration/ch12-gateway-api.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
