この用語をシェア
REST APIとは
REST API(RESTful API)は、REST(Representational State Transfer)というアーキテクチャスタイルの原則に基づいて設計されたWeb APIです。RESTという言葉は、Roy Fieldingが2000年に発表した博士論文「Architectural Styles and the Design of Network-based Software Architectures」の中で提唱した概念で、UDDI/WSDL/SOAPのような重厚なXMLベースのプロトコルスタックに対する、よりシンプルなWebの設計思想として整理されたものです。
重要なのは、RESTは「プロトコル」でも「規格」でもなく、あくまで「アーキテクチャスタイル(設計上の制約の集合)」だという点です。そのため「これがREST API仕様書だ」という唯一の公式ドキュメントは存在せず、後述する6つの制約をどこまで厳密に満たすかは実装者の裁量に委ねられています。実務上は、この制約を厳密に全部満たしたものだけを「REST API」と呼ぶのではなく、「HTTPのメソッドとURLでリソースを操作するJSON API」全般を指して緩やかに「REST API」もしくは「RESTful API」と呼ぶことが一般的です。この緩やかな用法と、Fieldingが定義した厳密なRESTを区別して語られる場面もあるため、「本当のRESTとは何か」という議論がしばしば起こる用語でもあります。
仕組み・詳細解説
REST成立に必要な6つの制約条件
Fieldingの論文では、REST APIと呼ぶために満たすべき制約が整理されています。全て満たすと「RESTfulである」、一部しか満たさなければ「REST風(RESTish)」と表現されることもあります。
| 制約 | 内容 |
|---|---|
| クライアント・サーバー分離 | UIとデータ保存の関心を分離し、それぞれ独立して進化できるようにする |
| ステートレス | サーバーはリクエスト間でクライアントのセッション状態を保持しない |
| キャッシュ可能 | レスポンスがキャッシュ可能かどうかを明示し、必要に応じて再利用する |
| 統一インターフェース | リソース識別・メッセージによる自己記述・HATEOAS・表現操作の4原則からなる、RESTの核となる制約 |
| 階層化システム | クライアントは直接オリジンサーバーと通信しているか、途中にゲートウェイやロードバランサーがあるかを意識しなくてよい |
| コードオンデマンド(任意) | サーバーがクライアントにスクリプトを送り実行させてもよい、という唯一の任意制約 |
この中で特に見落とされがちなのが「統一インターフェース」に含まれるHATEOAS(Hypermedia as the Engine of Application State)です。厳密なRESTでは、レスポンスに次に取りうる操作へのリンク(例えば注文リソースに"キャンセルする"操作へのURLを含める)を埋め込み、クライアントはURLをハードコードせずにハイパーメディアをたどって遷移すべきとされています。しかし実際に流通している「REST API」の大多数はHATEOASを実装しておらず、単純なJSON+HTTPメソッドの組み合わせに留まっています。これが「世の中のREST APIの多くは、厳密には"REST"ではない」と言われる理由です。
リソース指向のURI設計
RESTでは操作対象を「リソース」として捉え、URIはリソースの識別子として設計します。動詞ではなく名詞(多くは複数形)でパスを構成するのが基本ルールです。
| 良い例 | 避けるべき例 |
|---|---|
| GET /users/123/orders | GET /getUserOrders?id=123 |
| POST /orders | POST /createOrder |
| GET /users?status=active&sort=-created_at | GET /getActiveUsersSortedByDate |
コレクション(/users)は複数リソースの集合、単一リソース(/users/123)は特定の1件を指すという階層関係を保つこと、フィルタリング・ソート・ページネーションはパスではなくクエリパラメータで表現することが定石です。ネストは深くても2〜3階層までに留め、それ以上深くなる関係性はクエリパラメータ(例: /orders?userId=123)に切り替えるのが可読性の面で無難とされています。
HTTPメソッドと安全性・べき等性
REST APIはHTTPメソッドの意味論(セマンティクス)をそのままCRUD操作に対応させます。設計時に重要なのが「安全性(Safe)」と「べき等性(Idempotent)」という2つの性質です。安全性とはサーバーの状態を変更しないこと、べき等性とは同じリクエストを何度送っても結果が変わらないことを指します。
| メソッド | CRUD対応 | 安全 | べき等 |
|---|---|---|---|
| GET | Read(取得) | ○ | ○ |
| POST | Create(作成) | × | × |
| PUT | Update(全体更新) | × | ○ |
| PATCH | Update(部分更新) | × | 一般に×(実装依存) |
| DELETE | Delete(削除) | × | ○ |
PUTは「リソース全体を送信された内容で置き換える」操作のため、同じリクエストを何度送っても結果は同じ(べき等)です。一方PATCHは「差分だけを送る」ため、実装によってはべき等にならない場合があります(例えば「値を1加算する」ようなPATCHはべき等ではありません)。この違いを理解せずPUTとPATCHを混同すると、リトライ処理やクライアントの再送ロジックで意図しない不具合を生むことがあるため、API設計時にはメソッドごとのべき等性を明文化しておくことが実務上重要です。
ステートレス通信とキャッシュ制御
ステートレスとは、サーバーが「前回このクライアントが何をしたか」を記憶しないという性質です。ログイン状態のような情報も、サーバー側のセッションストアではなく、クライアントが毎回のリクエストに含めるトークン(Cookie、AuthorizationヘッダーのBearerトークンなど)で表現します。これにより、サーバーはどのインスタンスがリクエストを処理してもよくなり、ロードバランサー配下でのスケールアウトが容易になります。一方でトークンの検証コストが毎回発生する、リクエストのペイロードが大きくなりがち、というトレードオフもあります。
キャッシュ制御はHTTPの標準ヘッダーで表現します。Cache-Control: max-age=3600で有効期限を指定したり、ETagとIf-None-Matchヘッダーを組み合わせて「内容が変わっていなければ304 Not Modifiedを返す」といった条件付きリクエストを実現できます。GETのような安全なメソッドの結果を積極的にキャッシュ可能にしておくことは、RESTの制約の一つであると同時に、パフォーマンス改善の実務的な手段でもあります。
具体例(リクエスト・レスポンス)
ユーザーリソースを例に、基本的なCRUD操作のリクエストとレスポンスを示します。
// ユーザー一覧取得(ページネーション・絞り込み付き)
GET /api/v1/users?status=active&page=2&per_page=20
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
// レスポンス(200 OK)
{
"data": [
{ "id": 123, "name": "田中太郎", "email": "tanaka@example.com" }
],
"meta": { "page": 2, "per_page": 20, "total": 87 }
}
// 新しいユーザー作成
POST /api/v1/users
Content-Type: application/json
{
"name": "田中太郎",
"email": "tanaka@example.com"
}
// レスポンス(201 Created、Locationヘッダーで新規リソースのURLを返す)
Location: /api/v1/users/123
{
"id": 123,
"name": "田中太郎",
"email": "tanaka@example.com"
}
// 部分更新(メールアドレスのみ変更)
PATCH /api/v1/users/123
Content-Type: application/json
{ "email": "tanaka2@example.com" }
// エラー時のレスポンス例(400 Bad Request)
{
"error": {
"code": "VALIDATION_ERROR",
"message": "email はメール形式である必要があります",
"field": "email"
}
}
// ユーザー削除
DELETE /api/v1/users/123
// レスポンス:204 No Content(ボディなし)
実務では、成功時のレスポンスをdataキーで包み、一覧取得時にはページネーション情報をmetaキーに分離する、エラー時はerrorオブジェクトにコードとメッセージを統一フォーマットで格納する、といった「レスポンス全体の型を統一する」設計が定石です。これを怠ると、エンドポイントごとにレスポンス構造がバラバラになり、フロントエンド側の実装コストが増大します。
REST APIのメリット・デメリット
メリット
- シンプルさ:HTTPという既存の標準を基盤とするため、新たにプロトコルを学ぶ必要がなく、curlやブラウザからでも簡単に動作確認ができる
- スケーラビリティ:ステートレスなためサーバー側でセッションを共有する必要がなく、水平スケーリング(サーバー台数を増やす形の拡張)が容易
- キャッシュとの親和性:HTTPのキャッシュ機構(CDN、ブラウザキャッシュ、リバースプロキシ)をそのまま活用でき、GETリクエストの負荷を大きく下げられる
- 言語・プラットフォーム非依存:HTTPとJSONさえ扱えれば、どの言語・フレームワークからでも同じAPIを呼び出せる
- エコシステムの充実:OpenAPI(Swagger)、Postman、各種APIゲートウェイなど、設計・テスト・運用を支えるツールが豊富に揃っている
デメリット・課題
- オーバーフェッチ/アンダーフェッチ:エンドポイントが返すフィールドが固定のため、必要な項目だけ取得したくても余分なデータまで返ってきたり(オーバーフェッチ)、逆に足りずに複数回リクエストが必要になったり(アンダーフェッチ)することがある。この課題を解決する目的で登場したのがGraphQLである
- N+1的な複数リクエスト:関連するリソースを画面に表示するために、複数のエンドポイントへ順番にリクエストを送る必要があり、モバイル回線など高レイテンシ環境では体感速度が落ちやすい
- 厳密な契約(スキーマ)がない:REST自体にはリクエスト・レスポンスの型を強制する仕組みがなく、OpenAPIなど別の仕様と組み合わせないと、クライアントとサーバー間の型の食い違いに気づきにくい
- バージョニングの負債:仕様変更のたびに後方互換性を壊さないよう配慮する必要があり、運用が長期化するほどバージョン管理のコストが増す
- HATEOASの実装コスト:厳密なRESTが求めるハイパーメディアリンクの埋め込みは実装・保守の手間が大きく、多くの現場では省略されている(=「REST的だがRESTではない」実装が大半)
混同されやすい用語・類似技術との違い
「REST API」は他のAPIスタイルと混同されたり、逆に「REST APIと名乗っているが実際は違う」実装も多く存在します。代表的な比較対象を整理します。
| 技術 | REST APIとの違い |
|---|---|
| GraphQL | エンドポイントは基本1つで、クライアントがクエリで必要なフィールドだけを指定して取得する。オーバーフェッチ/アンダーフェッチを解消できる一方、HTTPキャッシュとの相性はRESTより劣り、サーバー側の実装も複雑になりやすい |
| gRPC | Googleが開発したRPC(リモートプロシージャコール)フレームワーク。Protocol Buffersでスキーマを厳密に定義し、HTTP/2上でバイナリ通信を行うため高速だが、ブラウザから直接呼び出すには制約があり、サービス間通信(マイクロサービスの内部通信)で使われることが多い |
| SOAP | XMLベースのメッセージ形式とWSDLによる厳格な契約を持つ、RESTより前から存在するプロトコル。金融・エンタープライズ系のレガシーシステムで今も使われるが、メッセージが冗長で学習コストも高く、新規開発でのシェアはREST・GraphQLに押されている |
| RPCスタイルAPI(似非REST) | URLに動詞を含む「/getUser」「/createOrder」のようなエンドポイント設計。HTTPとJSONを使っていても、リソース指向でもHTTPメソッドのセマンティクスも守っていないため、REST APIとは呼べない。世の中で「REST API」と呼ばれるものの中には、実質このRPCスタイルに近いものも少なくない |
| WebSocket | 双方向の常時接続を維持するプロトコル。REST APIはリクエスト・レスポンス型の一方向通信が基本のため、チャットやリアルタイム通知のような「サーバーから能動的にプッシュしたい」用途にはWebSocketの方が適している |
| Web API(広義) | 「Web API」はHTTP経由で提供されるAPI全般を指す広い言葉で、REST APIはその中の一設計スタイルにすぎない。SOAP APIやGraphQL APIも広義のWeb APIに含まれる |
実務での設計ポイント
ステータスコードの使い分け
- 200 OK:GET・PUT・PATCHなどの成功
- 201 Created:POSTによるリソース作成成功。Locationヘッダーで作成先URLを返すのが望ましい
- 204 No Content:DELETEなど、成功したがレスポンスボディを返さない場合
- 400 Bad Request:リクエストの形式・バリデーションエラー
- 401 Unauthorized:認証情報が無い・無効(認証の問題)
- 403 Forbidden:認証はできているが権限がない(認可の問題)
- 404 Not Found:指定したリソースが存在しない
- 409 Conflict:楽観的ロックの競合や、一意制約違反など状態の衝突
- 422 Unprocessable Entity:構文は正しいが意味的に処理できないリクエスト(バリデーションエラーの表現にも使われる)
- 429 Too Many Requests:レート制限超過。Retry-Afterヘッダーで再試行までの待ち時間を返すのが親切
- 500 Internal Server Error:サーバー側の予期しないエラー
401と403を混同する実装は多いが、「誰か分からない(401)」と「誰かは分かるが権限がない(403)」は原因も対処方法も異なるため、明確に使い分けるべきとされています。
バージョニング戦略
APIは公開後も進化するため、破壊的変更(フィールド名の変更、必須パラメータの追加など)を既存クライアントに影響を与えずに行う仕組みが必要です。代表的な方法は次の3つです。
- URIパスにバージョンを含める:/api/v1/users のようにパスで明示する。最も分かりやすく採用例が多い
- カスタムヘッダーで指定する:Accept: application/vnd.example.v2+json のようにメディアタイプでバージョンを表現する。URLは変わらないという利点がある
- クエリパラメータで指定する:?version=2 のように指定する方法。簡便だが省略時のデフォルト挙動の管理が煩雑になりやすい
どの方式でも、旧バージョンの廃止(サンセット)時期を事前に告知し、Deprecationヘッダーやドキュメントで明示しておくことが、外部にAPIを公開する際の実務的な作法です。
認証・認可とセキュリティ
- OAuth 2.0:第三者アプリケーションに限定的な権限だけを委譲する認可フレームワーク。認可コードフローが標準的で、SPAやモバイルアプリではPKCEの併用が推奨される
- JWT(JSON Web Token):署名付きトークンにユーザー情報やスコープを含め、サーバー側でセッションを持たずに認証状態を検証できる。トークンの有効期限管理と失効(リボーク)の仕組みが実装上の課題になりやすい
- APIキー:発行・検証がシンプルだが、ユーザー個人の認可とは紐付きにくく、漏えい時のリスクも大きいため社内システムや低リスクな用途に限定するのが無難
- HTTPS必須化:認証情報やトークンを平文でやり取りしないよう、HTTP通信は許可せずHTTPSのみを受け付ける(HSTSヘッダーの付与も推奨される)
- 入力値の検証とインジェクション対策:リクエストボディやクエリパラメータは必ずサーバー側でバリデーションし、SQLインジェクションやコマンドインジェクションにつながる文字列をそのままクエリに埋め込まない
- レート制限(スロットリング):IPやAPIキー単位でリクエスト数の上限を設け、429と共にRetry-Afterを返すことで、過負荷や不正利用(ブルートフォース攻撃など)を防ぐ
- CORSの適切な設定:ブラウザから異なるオリジンのAPIを呼び出す際は、Access-Control-Allow-Originを必要なオリジンだけに絞り、ワイルドカード(*)を安易に使わない
- 過剰な情報開示を避ける:エラーメッセージにスタックトレースや内部実装の詳細を含めない。500エラーの詳細はログにのみ記録し、レスポンスには汎用的なメッセージを返す
設計・運用を支える関連技術
- OpenAPI(旧Swagger):REST APIの仕様をYAML/JSONで記述する事実上の標準フォーマット。エンドポイント一覧やスキーマからドキュメントやモックサーバー、クライアントSDKを自動生成できる
- Postman/curl:APIを手動で叩いて動作確認するための代表的なツール。コレクション機能でテストケースをチームで共有できる
- APIゲートウェイ:認証・レート制限・ロギング・ルーティングなど、複数のAPIに共通する処理を集約するミドルウェア層。マイクロサービス構成では各サービスの前段に置くのが一般的
- JSON:REST APIのレスポンス形式として最も広く使われるデータ交換フォーマット。XMLに比べて軽量で、JavaScriptとの親和性が高い
2025〜2026年の最新動向
2025年以降、gRPCやtRPCといったREST以外の選択肢が特にマイクロサービス間通信・TypeScriptフルスタック開発の領域で採用を伸ばしていますが、外部公開APIやブラウザ向けAPIの領域では依然としてREST APIが最も広く使われる形式です。特筆すべき動きとして、AI/LLM系のサービス(チャット補完API、エンベディングAPIなど)の多くがREST形式のエンドポイントを提供しており、REST APIは「AIをアプリケーションに組み込む際の共通言語」としての役割も担うようになっています。
設計面では、OpenAPI仕様がバージョン3.1系で安定的に運用され、JSON Schemaとの整合性が向上したことで、API定義からドキュメント・型定義・テストコードまでを一気通貫で自動生成する「スキーマファースト」の開発スタイルが一般化しつつあります。また、REST APIのエンドポイントをそのままAIエージェントやLLMのツール呼び出し(Function Calling/Tool Use)として利用する事例が増えており、OpenAPIスキーマがAIエージェント向けのツール定義としても再利用される流れが広がっています。セキュリティ面では、単純なAPIキー認証からOAuth 2.0+短命なアクセストークンへの移行、レート制限やWAF(Web Application Firewall)によるボット対策の強化が、外部公開APIにおける実務的な標準になりつつあります。
よくある質問(FAQ)
Q. REST APIの6つの制約とは?
A. クライアント・サーバー分離、ステートレス、キャッシュ可能、統一インターフェース、階層化システム、コードオンデマンド(オプション)の6つです。特に統一インターフェースはリソース識別・自己記述メッセージ・HATEOAS・表現操作という4つの下位原則を含み、RESTの核となる制約です。全て満たすことは稀で、実務では緩やかな解釈で「REST API」と呼ぶことが一般的です。
Q. RESTful APIの認証方法は?
A. OAuth 2.0(標準的な認可フレームワーク)、JWT(トークンベース認証)、APIキー(シンプルだが安全性は低い)、Basic認証(開発時のみ推奨)が主な方法です。本番環境ではOAuth 2.0 + JWTの組み合わせが推奨され、いずれの方式でも通信はHTTPSで暗号化することが前提になります。
Q. API設計で避けるべきことは?
A. 動詞をURLに含める(/getUsers → /users)、ネストが深すぎるURL、不適切なHTTPステータスコードの使い回し(何でも200を返すなど)、バージョニングの欠如、エンドポイントごとにレスポンス構造が異なることが代表的なアンチパターンです。
Q. REST APIとGraphQL、結局どちらを選べばよいですか?
A. 一律の正解はありませんが、目安として、CRUD中心でリソース構造がシンプルな公開API・HTTPキャッシュを積極的に活用したい場合はREST APIが適しています。逆に、画面ごとに必要なデータの形が大きく異なり柔軟な取得条件が求められるフロントエンド(モバイルアプリの複雑な画面など)では、GraphQLがオーバーフェッチ/アンダーフェッチの課題を解決しやすい場合があります。両者を併用し、外部公開はREST、内部の画面用集約層はGraphQLとする構成も実務では珍しくありません。
Q. PUTとPATCHはどう使い分ければよいですか?
A. リソース全体を丸ごと置き換える場合はPUT、一部のフィールドだけを更新する場合はPATCHを使うのが原則です。PUTはべき等性が保証されますが、PATCHは実装次第でべき等にならない場合がある点に注意し、クライアント側のリトライ処理を設計する際はこの違いを踏まえる必要があります。
