API設計ガイド

RESTful APIの原則、HTTPステータスコードの適切な利用、エンドポイント設計、バージョン管理などを学びます。

学習をスタートする

ロードマップ

1

RESTの原則とエンドポイント設計

モダンWebシステムにおいて、システム間でデータを受け渡しするための「API」の設計は極めて重要です。本章では、最も広く採用されている REST(Representational State Transfer) の考え方と、直感的で使いやすいエンドポイント(URI)の設計手法について解説します。 1. RESTの基本概念 RESTは、Webの仕組みを最大限に活用するために提唱されたソフトウェアアーキテクチャスタイルです。RESTの原則に則って設計されたAPIを RESTful API と呼びます。 RESTの主要な4原則 1. アドレス可能性 (Addressability): すべての提供される情報(リソース)が、一意のURI(Uniform Resource Identifier)で表現されること。 2. 統一インターフェース (Uniform Interface): 情報の取得、作成、更新、削除を、HTTPで定義された標準メソッド(GET, POST, PUT, DELETEなど)の組み合わせで行うこと。 3. 接続性 (Connectability): 返されるリソースの中に、他のリソースへのリンクを含めることができること(HATEOASという概念)。 4. ステートレス性 (Stateless): サーバー側でクライアントのセッション状態(ログイン状態など)を管理せず、各リクエストは独立して処理されること。 2. リソース指向のエンドポイント設計 RESTful APIでは、エンドポイントのパスを「実行する処理(動詞)」ではなく、「操作対象のデータ(名詞)」 で表現するのが大原則です。 リソース表現の構造(図解) ユーザーがブログ記事を操作するシステムを例に、リソースの親子関係とURIの設計を整理します。 良い設計と悪い設計の比較 操作内容 悪い設計(処理ベース) 良い設計(リソースベース) ユーザー一覧の取得 GET /getAllUsers GET /users 新規ユーザーの作成 POST /createUser POST /users 特定のユーザー取得 GET /getUser?id=123 GET /users/123 ユーザー情報の更新 POST /updateUser/123 PUT または PATCH /users/123 ユーザーの削除 GET /deleteUser?id=123 DELETE /users/123 設計上の重要なルール * リソース名は複数形を使う: /user ではなく /users と表現することで、コレクション(集合)であることを明示します。 * 小文字を使用し、ハイフンで繋ぐ: URIは大文字小文字を区別する場合があるため、すべて小文字で統一します。単語の区切りにはアンダースコア(_)ではなく、ハイフン(-)を使用します。 - ◯: /user-profiles - ×: /user_profiles や /userProfiles * 階層構造はサブリソースで表現する: /users/123/orders のように、親子関係があるリソースは親リソースの下にネストさせます。ただし、ネストの階層は2〜3階層までに留め、深くなりすぎないようにします。 まとめ * RESTful APIは、リソース(名詞) をURIで示し、HTTPメソッド(動詞) で操作する。 * URIは小文字で統一し、複数形を使用し、動詞を排除してシンプルに保つ。

2

HTTPメソッドとステータスコードの使い分け

RESTful APIの強みは、HTTPプロトコルの標準仕様(メソッドやステータスコード)をそのまま利用することで、自己記述的(自己解決的)なAPIを実現できる点にあります。本章では、HTTPメソッドとステータスコードの正しい使い分けについて解説します。 1. HTTPメソッドの役割と性質 APIクライアントがどのような操作を行いたいかは、HTTPメソッドによって表されます。 主要なHTTPメソッド * GET: リソースを取得します。リクエストボディを持ちません。 * POST: 新しいリソースを作成します。または、冪等(べきとう)ではない汎用的な処理を実行します。 * PUT: 既存のリソースを完全に置き換えます。指定されたURIにリソースが存在しない場合は、新規作成します。 * PATCH: 既存のリソースを部分的に更新します。 * DELETE: リソースを削除します。 「安全性」と「冪等性(べきとうせい)」 APIの信頼性を設計する上で、以下の2つの概念を理解することが不可欠です。 1. 安全性 (Safety): 操作を実行しても、サーバー上のリソースの状態が変化しない性質(読み取り専用)。 2. 冪等性 (Idempotency): 同じ操作を1回実行しても、何回実行しても、サーバー上の結果が同じになる性質。 メソッド 安全性 冪等性 動作の特徴 GET ◯ ◯ 何度取得してもデータは変わらない POST × × 複数回送信すると、その分リソースが新しく重複作成される PUT × ◯ 完全に上書きするため、何回送信しても同じ状態に収束する PATCH × × 部分更新のため、加算処理などを行うと結果が変わる場合がある DELETE × ◯ 2回目以降の削除は「既に存在しない」ため、リソースの状態は変わらない 2. HTTPステータスコードの設計 サーバーは、処理結果をHTTPステータスコードを使ってクライアントに通知します。これにより、クライアントはレスポンスボディをパースする前に処理の成否を判断できます。 代表的なステータスコード一覧 2xx Success(成功) * 200 OK: リクエスト成功。主に GET や PATCH などの成功時に返します。 * 201 Created: リクエストによりリソースの作成が成功。主に POST 時に返します。レスポンスには作成されたオブジェクトを含めるか、Location ヘッダーに新URIを含めます。 * 204 No Content: リクエストは成功したが、返すべきレスポンスボディがない。主に DELETE や一部の更新成功時に返します。 4xx Client Error(クライアント側の問題) * 400 Bad Request: 入力バリデーションエラーなど、クライアントのリクエスト形式が不正。 * 401 Unauthorized: 認証情報がない、または無効。ログインが必要であることを示します。 * 403 Forbidden: 認証されているが、そのリソースに対するアクセス権限がない。 * 404 Not Found: 指定されたURIのリソースが存在しない。 5xx Server Error(サーバー側の問題) * 500 Internal Server Error: サーバー内部で予期しない例外が発生(バグなど)。 * 503 Service Unavailable: サーバーの過負荷やメンテナンス中で処理が一時的に実行不可。 3. 統一されたエラーレスポンス エラー(4xx, 5xx)を返す際は、ステータスコードだけでなく、クライアントがプログラムでハンドリングしやすいよう、統一されたJSON形式のエラー情報をボディに含めるのが良いプラクティスです。 良いエラーレスポンスの例 このように構造化されたエラー情報を返すことで、フロントエンドでのユーザー向けメッセージの出し分けが容易になります。 まとめ * GET/PUT/DELETE は 冪等(べきとう) に設計する。 * ステータスコード を適切に使い分けることで、クライアントに明確な結果を提示する。 * エラー発生時は、フロントエンドが処理しやすい 統一されたエラーフォーマット を返す。

3

APIバージョン管理とセキュリティ

APIを一般に公開し、長期間運用するにあたっては、破壊的変更からクライアントを守る「バージョン管理」と、不正アクセスを防ぐ「セキュリティ対策」の設計が欠かせません。本章では、これらの設計パターンについて解説します。 1. APIのバージョン管理 APIのデータ構造や仕様を変更する際、既存のクライアントが動作しなくなる「破壊的変更」が発生する場合があります。これを避けるため、複数のバージョンを並行して稼働させる仕組みが必要です。 3つのバージョン管理手法 1. パス型 (URI Path Versioning) — 推奨 最も一般的で分かりやすい手法です。URIの先頭付近に /v1 などの識別子を埋め込みます。 * メリット: ルーティングやプロキシでのキャッシュが非常に容易。 * デメリット: バージョンが変わるたびにベースURIが変更になる。 2. クエリパラメータ型 (Query Parameter Versioning) リクエストのパラメータとしてバージョンを渡します。 * メリット: URIのパス自体は変わらない。 * デメリット: キャッシュの制御やルーティングがやや複雑になる場合がある。 3. メディアタイプ型 / ヘッダー型 (Accept Header Versioning) Accept ヘッダー(あるいはカスタムヘッダー)を使って、要求するバージョンを伝えます。 * メリット: クリーンなURI(同一リソースを表す単一のURI)を維持できる。 * デメリット: ブラウザから直接テストしにくく、プロキシキャッシュが難しい。 2. APIセキュリティの基本 認証されていないクライアントからのアクセスを防ぎ、誰がリクエストを送信しているのかを特定するための仕組みです。 代表的な認証・認可方式 1. APIキー (API Key): サービス登録時に各クライアントに発行される静的な文字列です。主に一般公開されているデータの取得(天気情報、地図情報など)で使われ、ヘッダー(X-API-Key など)に入れて送信します。 2. トークン認証 (JWT - JSON Web Token): ユーザーがID/パスワードでログインした後、サーバーが署名付きの暗号化トークン(JWT)を発行します。クライアントはこれ以降のリクエストヘッダーに以下のように含めます。 サーバー側はセッションデータベースに問い合わせることなく、トークンの署名を検証するだけでユーザーを識別できるため、スケーラビリティに優れています。 3. OAuth 2.0 / OIDC (OpenID Connect): サードパーティアプリに対して、ユーザーのパスワードを開示することなくアクセス権限を与える(認可)ための業界標準プロトコルです。 3. その他の重要なセキュリティ対策 * レート制限 (Rate Limiting): DoS攻撃やAPIの過剰な呼び出しを防ぐため、IPアドレスやトークン単位で「1分あたり100回まで」といった制限を設けます。制限を超えた場合は 429 Too Many Requests を返します。 * 入力の厳格なバリデーション: SQLインジェクションやOSコマンドインジェクションなどを防ぐため、すべてのリクエストボディやクエリパラメータをサーバー側で厳格に検証します。 まとめ * APIの破壊的変更を防ぐため、パス型 (URIパスに /v1/ を含む方式) によるバージョン管理を優先する。 * セッション管理がないステートレスなAPIでは、JWTを用いた Bearer 認証 が広く使われる。 * 過度な負荷や攻撃を防ぐため、レート制限 (429 Too Many Requests) を導入する。

4

GraphQL、gRPC、tRPC とスキーマ駆動開発

本コースの前半では、従来のデファクトスタンダードである REST API の設計方法について学びました。しかし、Webアプリケーションの規模が拡大し、多様なデバイスや複雑なデータ連携が必要となるにつれ、REST API だけでは対応しきれない課題も浮き彫りになってきました。 第4章では、REST の課題を克服するために登場した GraphQL、gRPC、tRPC という現代的なAPIプロトコルの概要と、開発効率を最大化する 「スキーマ駆動開発」 の重要性について解説します。 1. REST API の限界と新たな課題 REST API はシンプルで使いやすい反面、以下のような課題を抱えています。 * オーバーフェッチ (Over-fetching): 画面の表示に「ユーザー名」だけが必要なのに、APIを叩くと「住所」「履歴」など大量の不要なデータが返ってくる。 * アンダーフェッチ (Under-fetching): 1つの画面を表示するために、「ユーザー情報」「注文一覧」「おすすめ商品」のように、何回も個別のAPIリクエストを送信しなければならない。 * 型安全性の不足: APIの仕様変更(パラメータの変更や削除)が、フロントエンドに静的に伝わらず、ランタイムエラー(画面崩れやバグ)になって初めて気づくことが多い。 2. 現代のAPIプロトコル三銃士 これらの課題を解決するため、ユースケースに応じて以下のプロトコルが使い分けられます。 ① GraphQL (グラフQL) * 特徴: クライアントが「必要なデータの構造」をクエリ言語で指定してリクエストする仕様。 * メリット: オーバーフェッチ/アンダーフェッチを完全に解消。1つのエンドポイントで柔軟なデータ取得が可能。 * 適した用途: 画面ごとに必要なデータ構造が細かく変わる複雑なフロントエンドアプリ(SNSやダッシュボード)。 ② gRPC (ジーアールピーシー) * 特徴: Googleが開発した高性能なRPC(遠隔手続き呼び出し)フレームワーク。通信にはJSONの代わりにバイナリ形式の Protocol Buffers を使用します。 * メリット: 高速・低遅延、かつ軽量。双方向ストリーミング通信が容易。 * 適した用途: マイクロサービス同士の通信や、高頻度で軽量なデータ通信が求められるバックエンド間の連携。 ③ tRPC (ティーアールピーシー) * 特徴: TypeScript 専用の RPC ライブラリ。バックエンドのルーター型定義を、フロントエンドへ直接インポートして使用します。 * メリット: スキーマファイルの記述やコード生成(Code Generation)を一切行うことなく、完全なフロント・バック間の型安全性を実現。 * 適した用途: フロントエンドとバックエンドが同じ TypeScript で開発されているモノレポ(Next.jsなどのフルスタック環境含む)プロジェクト。 APIプロトコル比較マトリクス 項目 REST API GraphQL gRPC tRPC 通信フォーマット 主に JSON JSON Protocol Buffers (バイナリ) JSON スキーマ定義 任意 (OpenAPI 等) 必須 (GraphQL Schema) 必須 (proto ファイル) TypeScriptの型定義 (自動) 主なメリット 標準的、キャッシュしやすい 必要なデータだけを取得可能 高速・高パフォーマンス スキーマなしで型安全 主なデメリット 通信回数やデータ量が増えやすい クエリ解析のオーバーヘッド ブラウザからの直接接続が不便 TypeScript (JS) 依存 3. スキーマ駆動(スキーマファースト)開発 どのようなAPIプロトコルを採用するにせよ、現代の開発現場では 「スキーマ駆動開発(Schema-driven Development)」 が強力に推奨されています。 これは、プログラムコードを書く前に、まず APIの仕様書(スキーマファイル)を決定し、それを正(Single Source of Truth)としてフロントエンドとバックエンドが並行して開発を進める手法 です。 スキーマ駆動開発がもたらすメリット 1. パラレル開発の実現: スキーマが決まれば、フロントエンドはモックデータ(ダミーのAPI応答)を使って、バックエンドの実装完了を待たずに画面開発を進められます。 2. 型定義の自動生成: swagger-typescript-api や graphql-codegen などのツールを用いることで、スキーマからTypeScriptの型やAPIクライアントコードを自動生成できます。これにより、手動での書き写しミスが完全にゼロになります。 3. 仕様のドキュメント化: スキーマ定義そのものが常に最新のAPI仕様書(Swagger UIなど)としてレンダリングされるため、ドキュメントの更新漏れが発生しません。 まとめ * REST API はオーバーフェッチ/アンダーフェッチや型安全性の担保に課題がある。 * GraphQL はクライアントが取得項目を制御し、gRPC は高速バイナリ通信、tRPC は TypeScript モノレポに最適。 * スキーマ駆動開発 は、APIの設計図(スキーマ)を開発の起点とすることで、並行開発の加速、型の自動生成、仕様の乖離防止を実現する現代の開発パラダイム。

5

APIドキュメンテーションとガバナンス

Web APIは作成して終わりではありません。多くの開発者やシステムに利用されるAPIは、正確な「ドキュメンテーション」と、変更に対するルールである「ガバナンス」が不可欠です。 第5章では、OpenAPIを用いた現代的なドキュメント管理手法と、APIを安全に変更・維持するためのガバナンス設計について解説します。 1. スキーマファースト開発とOpenAPI 現代のAPI開発では、コードを書く前にAPIの仕様を記述する 「スキーマファースト開発(Schema-first Development)」 が主流です。この中心的な標準規格が OpenAPI Specification (OAS)(旧Swagger)です。 スキーマファーストの利点 1. 並行開発の実現: バックエンドの実装完了を待たずに、定義されたスキーマからモックサーバー(Prism等)を立ち上げてフロントエンドが開発を進められます。 2. 仕様の齟齬の削減: 仕様が明文化されるため、結合テスト時のパラメータ名の違いなどのイライラが解消されます。 3. ドキュメントの自動化: 定義ファイル(YAML/JSON)からインタラクティブなAPIドキュメント(Swagger UIやRedoc)を常に最新の状態で配信できます。 2. APIのバージョニング管理 APIをアップデートする際、既存のクライアントを壊さないためにバージョニングが必要です。主に以下の3つの手法があります。 バージョニング手法 指定方法の例 メリット デメリット パス(URI) https://api.example.com/v1/users 最も直感的でキャッシュしやすい バージョンごとにURLが変わり、移行コストが高い クエリパラメータ https://api.example.com/users?version=1 シンプルに実装できる ルーティングやキャッシュ管理が複雑になる カスタムヘッダー Accept: application/vnd.company.v1+json URLが常に一定に保たれる ブラウザでの動作確認やキャッシュが難しくなる セマンティックバージョニングの適用 一般的に、APIのバージョン表現には セマンティックバージョニング(SemVer)(例: vMajor.Minor.Patch)が参考にされます。 * Major (破壊的変更): 後方互換性のないAPIの変更(エンドポイントの削除、必須パラメータの追加など)。URLの /v1/ を /v2/ に変更する。 * Minor (機能追加): 後方互換性がある機能の追加(任意パラメータの追加、新しいエンドポイントの追加)。 * Patch (バグ修正): 後方互換性があるバグ修正(ドキュメントの修正、内部ロジックの改善)。 3. 後方互換性と非推奨化(Deprecation) APIをアップグレードする際、古いバージョンを即座に停止することはできません。以下の手順を踏んで安全に移行(ディプリケーション)を進めます。 安全な廃止フロー 1. Deprecation ヘッダー: レスポンスヘッダーに Deprecation: true や、廃止予定日を示す Sunset ヘッダーを含めることで、クライアントの開発者へ移行を促します。 2. ドキュメントの更新: APIドキュメント上に deprecated フラグを立て、非推奨であることを視覚的に明示します。 APIドキュメントと適切なバージョニングルールを整備することで、開発者にとって信頼性が高く、長く持続可能なAPIを提供できるようになります。