REST API完全ガイド:設計原則・HTTPセマンティクス・セキュリティと実践ベストプラクティス
REST API とは — 概要
REST(Representational State Transfer)は、2000年にロイ・フィールディング(Roy Fielding)が博士論文で提唱したソフトウェアアーキテクチャのスタイルで、特にWeb上の分散システム設計に適しています。REST APIは、このアーキテクチャ原則に沿って設計されたAPIのことを指し、HTTPの既存の機能(URI、メソッド、ステータスコード、ヘッダ、メディア型など)を利用してクライアントとサーバ間の通信を行います。
REST の定義と主要な制約(Constraints)
RESTはプロトコルそのものではなく設計原則の集合です。FieldingはRESTを満たすために以下の6つ(うち1つは任意)の制約を挙げています。これらを満たすことで、スケーラブルで拡張可能、かつ保守しやすいシステム設計を目指します。
- クライアント–サーバ(Client–Server):責務の分離。ユーザーインターフェースとデータストレージの分離により、独立した進化が可能。
- ステートレス(Stateless):各リクエストはサーバ側にクライアントのセッション状態を保持しない(必要な情報は各リクエストに含める)。これによりスケーリングと障害復旧が容易になる。
- キャッシュ可能(Cacheable):レスポンスが明示的にキャッシュ可能かどうかを示し、再利用を促進することでパフォーマンスを向上。
- 統一インターフェース(Uniform Interface):システムの単純化と相互運用性の向上を目的とし、リソースの識別、リソース表現、自己記述メッセージ、ハイパーメディア(HATEOAS)の4つの要素を含む。
- 階層化システム(Layered System):中間層(ロードバランサ、キャッシュ、ゲートウェイなど)を導入でき、クライアントは最終エンドポイントを直接認識しなくてよい。
- コードオンデマンド(Code on Demand) — 任意:サーバがクライアントにスクリプトやコードを送信して機能を拡張できる(例:JavaScript)。任意なので必須ではない。
HTTP と REST の関係
RESTはHTTPを前提とすることが多く、URIでリソースを識別し、HTTPメソッド(GET、POST、PUT、PATCH、DELETEなど)で操作を表現します。重要なのは、HTTPの意味(セマンティクス)を尊重することです。例えばGETは「安全(safe)」かつ「副作用のない」読み取り操作を意味し、PUTやDELETEは冪等(idempotent)であることが期待されます(RFC 7231に詳述)。
リソース設計 — URI、表現、メディアタイプ
- URI設計の基本
URIは操作を表すのではなく「リソース」を表すべきです。一般的な慣習としては名詞の複数形を使い、階層的にネストして関係性を表現します。例:/users、/users/{userId}/orders。
- 表現(Representation)
リソースは様々な表現(JSON、XML、HTMLなど)で表されます。実務ではJSONが最も一般的です。表現はリソース状態のスナップショットであり、適切なメディアタイプ(Content-Type)で返却されます。
- コンテンツネゴシエーション
クライアントはAcceptヘッダで希望するメディアタイプを示し、サーバは応答する表現を選択できます(例:application/json、application/xml)。
代表的なHTTPメソッドと使い分け
- GET — リソースの取得(安全かつ冪等)。レスポンスはキャッシュ可能であることが多い。
- POST — 新規リソース作成やサーバ側での処理実行(非冪等)。サブミッションや検索(複雑なクエリ)に使われることもある。
- PUT — 指定したURIにリソースを完全に置換(冪等)。存在しなければ作成する場合もある。
- PATCH — リソースの部分更新(部分的な変更、通常は冪等でない場合もあるが設計次第)。
- DELETE — リソースの削除(冪等)。
状態コード(HTTP Status Codes)の運用例
正しいステータスコードの使用はクライアントとサーバの協調に重要です。頻出の例:
- 200 OK — 成功(GET, PUTなど)。
- 201 Created — リソース作成に成功(POST)。Locationヘッダで作成URIを返す。
- 204 No Content — 成功だがレスポンスボディなし(DELETEやPUTの成功時に利用)。
- 400 Bad Request — リクエストが不正(バリデーションエラーなど)。
- 401 Unauthorized — 認証が必要。
- 403 Forbidden — 認可されていない操作。
- 404 Not Found — リソースが存在しない。
- 409 Conflict — 競合(例:重複作成やバージョン競合)。
- 429 Too Many Requests — レート制限に達した。
- 5xx — サーバ内部エラー。
実践的な設計パターンとベストプラクティス
- リソースの命名
URIはわかりやすく、予測可能に。動詞ではなく名詞、複数形を推奨。例:/articles、/users/{id}/orders。
- フィルタリング、ソート、ページング
大量データの取り扱いにはクエリパラメータを使用:?page=2&limit=20、?sort=-created_at、?status=published といった形。
- 部分更新の選択(PATCH vs PUT)
部分更新にはPATCH(JSON Patch, JSON Merge Patchなどの仕様を明確に)。PUTは完全置換を念頭に。
- 冪等性と安全性
クライアントは再試行による副作用を考慮する。PUTやDELETEは冪等であるよう設計し、POSTは非冪等であることを許容する。
- ハイパーメディア(HATEOAS)
リソース表現に次に取るべきアクションへのリンクを含め、クライアントを導く設計。ただし実務では完全なHATEOASを採用するケースは限定的で、多くはリンクやURIテンプレートのみを部分的に利用する。
- 一貫したエラー表現
エラーは構造化されたJSONで返す(例:{ "status": 400, "error": "Bad Request", "message": "...", "errors": [...] })。API利用者が解析しやすい形に。
認証・認可とセキュリティ
REST APIのセキュリティは非常に重要です。代表的な手法を挙げます。
- TLS(HTTPS):常時TLSを利用し、通信を暗号化する。プレーンHTTPは避ける。
- APIキー:簡易的な認証。サーバ側でキーを発行し、ヘッダやクエリで送信(ただし露出リスクあり)。
- OAuth 2.0:第三者認可やアクセストークン発行に広く利用される(RFC 6749)。
- JWT(JSON Web Tokens):自己完結型トークン。署名により改ざん検知が可能だが、失効管理は注意が必要。
- CORS(Cross-Origin Resource Sharing):ブラウザ利用時のオリジン制御。許可されたオリジンやメソッドのみを許可する。
- CSRF対策:ブラウザからの状態変更リクエストに対する保護。トークンベースの設計やSameSiteクッキーの利用。
- 入力検証と出力エスケープ:SQLインジェクションやXSS、その他の脆弱性対策を徹底する。OWASP API Security Top 10 などを参照。
キャッシュとパフォーマンス
キャッシュはパフォーマンス向上とスケーラビリティの鍵です。HTTPのCache-Control、ETag、Last-Modified、Expiresなどのヘッダを適切に設定することで、不要なリクエストを減らせます。ステートレス設計とあわせてロードバランシング、CDNの利用、バックエンドでのページングやインデックス設計も重要です。
エラーハンドリング、バージョニング、互換性
- エラーハンドリング:一貫したエラー形式、適切なステータスコード、詳細は開発者向けドキュメントで明示。
- バージョニング:互換性を保つためにAPIの変更管理が必須。一般的手法は
- URIバージョン(/v1/users)
- ヘッダによるバージョン(Accept: application/vnd.example.v1+json)
- クエリパラメータ(?version=1)(実務ではあまり推奨されない)
- 後方互換性の維持:可能な限り非破壊的な変更(フィールド追加はOK、削除や意味変更はNG)。破壊的変更は新バージョンで提供。
ドキュメンテーションとツール
良いAPIは良いドキュメントを持ちます。OpenAPI(旧Swagger)などの仕様を使えば、機械可読なAPI定義からドキュメントやクライアントSDKを自動生成できます。Postmanやcurl、APIゲートウェイ(AWS API Gatewayなど)を用いたテスト/監視も標準的です。テストはユニット、統合、契約テスト(consumer-driven contract)を組み合わせると堅牢です。
REST の限界と代替アプローチ
RESTは広く使われていますが万能ではありません。複数リソースを横断して必要なデータを1回のクエリで取得したい場合、RESTだと複数リクエストが必要になることがあります。こうした場面ではGraphQLのようなクライアント主導のクエリ言語が有効です。また、高度なストリーミングや双方向通信(リアルタイム)にはWebSocketやgRPCのようなプロトコルが適しています。設計はユースケースに応じて選択すべきです。
実用的な例(簡易)
ユーザーリソースを扱う典型的なエンドポイント例:
- GET /users — ユーザー一覧(フィルタ、ソート、ページング対応)
- POST /users — ユーザー作成(201 Created、Locationヘッダに /users/{id})
- GET /users/{id} — 指定ユーザー取得(200)
- PUT /users/{id} — 指定ユーザーを完全更新(200または204)
- PATCH /users/{id} — 指定ユーザーを部分更新(200)
- DELETE /users/{id} — 指定ユーザー削除(204)
例:ユーザー作成のレスポンス(201)
HTTP/1.1 201 Created
Location: https://api.example.com/users/123
Content-Type: application/json
{
"id": 123,
"name": "山田 太郎",
"email": "taro@example.com"
}
まとめ — 守るべきポイント
- RESTはアーキテクチャスタイルであり、設計原則(ステートレス、キャッシュ、統一インターフェースなど)を理解することが重要。
- HTTPのセマンティクスを尊重し、適切なメソッドとステータスコードを使用する。
- セキュリティ(TLS、認証・認可、入力検証)は最優先で設計する。
- ドキュメンテーション(OpenAPI等)と一貫したエラー形式、バージョニング戦略を用意する。
- ユースケースに応じてREST以外の技術(GraphQL、gRPC、WebSocketなど)を検討する柔軟性も持つ。
参考文献
- Roy T. Fielding, "Architectural Styles and the Design of Network-based Software Architectures"(博士論文)
- RFC 7231 - HTTP/1.1: Semantics and Content
- RFC 7234 - HTTP/1.1: Caching
- RFC 6749 - The OAuth 2.0 Authorization Framework
- MDN Web Docs — REST(日本語)
- OWASP API Security Project
- OpenAPI Specification(Swagger)
- JSON:API — A specification for building APIs in JSON
- GraphQL — A query language for APIs


