API設計の原則と拡張性確保

2026.02.14
API設計の原則と拡張性確保

API設計の原則と拡張性確保

事業要件から逆算する「契約」としてのAPI

APIは実装の詳細ではなく「契約」です。契約は頻繁に変えない前提で、将来の拡張を前提に設計します。最初に決めるのは技術ではなく、ユースケースと変更コストです。誰が、いつ、どの操作を、どの頻度で行い、どの失敗が致命的か。ここを言語化してから次の原則に落とし込みます。

  • リソース指向と一貫性: 名詞で表現し、/orders/{id}/items のように階層は浅く。動詞は状態遷移(/orders/{id}: PATCH で status=shipped)に寄せます。
  • 同期/非同期の切り分け: 重い処理はジョブキュー化し、受理のみを200系で返し、結果はWebhooksやポーリングで取得。
  • 冪等性: POSTでもIdempotency-Keyを受け付け、重複作成を防止。決済・予約・在庫は必須です。
  • 標準化したエラー: machine-readableなcode、人間向けmessage、原因のhint、再試行可否、関連ドキュメントURLを返却。
  • 権限とスコープ: 最小権限のスコープ設計。監査ログに誰が何をしたかを残す前提でAPIを切る。
  • SLO前提の契約: レイテンシ目標(例 p95 < 300ms)、整合性モデル(強い/結果整合)を公開。

拡張性を確保する具体パターン

後方互換の原則とバージョニング

  • 「追加はOK、削除・意味変更はNG」を基本に。新規フィールドはオプショナルで、既存レスポンスを壊さない。
  • バージョンはURL版(/v1)かヘッダ版(Accept: application/vnd.example.v1+json)。長寿命APIはヘッダ版が移行しやすい。
  • 非推奨ポリシー: Deprecation/Sunsetヘッダ、移行ガイド、EOL日程(例 6か月)を明示。v1とv2は一定期間並行稼働。

応答の拡張余地

  • エンベロープ: { data, meta, errors } の枠を固定し、metaにページ情報や実験フラグを追加可能に。
  • スパースフィールド: fields=price,name のように必要なフィールドのみ取得。無駄な拡張でも既存クライアントが壊れにくい。
  • ページングはカーソル型: offsetは遅延や重複に弱い。nextCursor/prevCursorを返却し、安定した並び順と組み合わせる。
  • 検索/フィルタの語彙固定: sort=-createdAt、filter[status]=active のようにキーを体系化。

可観測性と信頼性のための仕様

  • 相関ID: リクエストID(例 X-Request-Id)を要求/応答で往復。分散トレーシングヘッダ(traceparent)もサポート。
  • レート制御: 429時にRetry-Afterを返却。X-RateLimit-Remaining等で利用者が自律的に制御できるように。
  • リトライの指針: 冪等エンドポイントのみ再試行可。タイムアウト閾値やバックオフ規則をドキュメント化。

イベント連携の進化可能性

  • Webhooksのバージョン管理と署名検証。再送戦略(指数バックオフ、最大再送回数)と順序保証の扱いを明記。
  • 「アウトボックス」パターンで整合性を担保。書き込みとイベント公開の原子性を保つ。

スキーマ進化の実務

  • OpenAPI/JSON Schemaを単一の真実源に。nullableとoptionalを厳密に区別。
  • 列挙型は追加のみ許容。未知値は無視できるようクライアントに指針を提示。
  • 将来拡張のためのreservableフィールド(extensions: { … })を許すが、乱用は避ける。

運用で拡張性を腐らせない仕組み

  • Contract-first: スキーマからサーバ/SDK/スタブを自動生成。PRでスキーマ差分を機械検出し、破壊的変更をブロック。
  • コンシューマ駆動契約テスト: 主要クライアントの期待挙動を契約化し、デプロイ前に検証。
  • ドキュメントは実行可能に: サンプルリクエスト、Try-it-out、レート/エラー事例、移行ガイドを常設。
  • 段階的リリース: フィーチャーフラグ、カナリア、影トラフィックで互換性を実証。v1/v2の二重書き込み期間を計画。
  • 可観測性: p95レイテンシ、5xx率、429発生率、Webhook成功率、依存先のヘルスをダッシュボード化。エラーバジェットで変更速度を調整。
  • 鍵・権限制御: テナント別のレートリミットとスコープ。漏洩時のローテーションフローを標準化。

生成AIや開発支援APIの統合では、とくに抽象化が重要です。ChatGPT、Claude、Gemini、Copilotのように提供元ごとにモデル識別子やトークン課金、タイムアウト特性が異なります。モデルIDやプロンプト雛形を構成として外出しし、応答を内部標準に正規化、可重試/不可重試の判定を共通化すると、将来のモデル追加・切替が容易になります。

身近な企業活用例:求人連携APIの再設計で苦情ゼロに

従業員120名規模の人材サービス会社。自社求人データを外部媒体に配信するAPIを社内で急造し、数社のパートナーが利用を開始。しかし、以下の問題が噴出しました。

  • ページングがoffset固定で、同期時に抜け・重複が発生。重い時間帯に5xxが増加。
  • レスポンスに不要な巨大フィールドが常に含まれ、転送量が増大。
  • 仕様変更を口頭で伝達し、互換を壊す更新が発生。パートナー側で障害が連鎖。
  • Webhookの署名・再送がなく、一時的な障害でイベントが失われる。

これに対し、3か月で次の改善を実施しました。

  • OpenAPIで契約を定義し、スキーマ差分チェックをCIに導入。破壊的変更は自動検知でブロック。
  • カーソルページングへ移行し、安定キー(updatedAt,id)で並び順を固定。スパースフィールド指定(fields)を提供。
  • ヘッダ版バージョニングとDeprecation/Sunsetヘッダを運用。v1とv2を6か月並行稼働し、移行ガイドを同梱。
  • Webhookに署名検証、指数バックオフ、最大再送回数、イベントIDの重複排除を実装。
  • Idempotency-Keyを受け付け、求人作成の二重登録を防止。エラーレスポンスにcodeと再試行方針を明記。

結果、同期時の重複・欠落は体感ゼロに近づき、p95レイテンシは40%以上短縮。5xx率は月次で半減し、サポート問い合わせは約3分の1に。新規パートナーの導入期間は平均2週間短縮され、社内チームも仕様変更の心理的コストが大幅に下がりました。とくに「追加はOK、削除・意味変更はNG」という原則と、エンベロープ+スパースフィールドの組み合わせが、拡張余地と安定稼働の両立に効きました。

APIはソフトウェアというより、他社・他部署との長期契約です。仕様の言語化、互換性ポリシー、観測と移行の仕組みを最初に埋め込むことが、将来の速度と信頼を担保します。受託開発ソリューション事業の現場では、要件定義から契約テスト、ドキュメント運用、段階的リリース、EOL管理までを一連のプロセスとして設計・実装・運用に落とし込み、事業の変化に耐えるAPI基盤づくりを支えています。