はじめに
「APIのエンドポイント名、/getUsers でいいかな?」
もしそう思ったなら、この記事を読んでから設計を始めてください。REST APIには 「こう設計すべき」という基本原則 があり、それを知っているかどうかで、APIの使いやすさと保守性が大きく変わります。
この記事では、REST APIの リソース設計、エンドポイント命名規則、ステータスコードの使い分け、べからず集 を図解で解説します。
この記事は 「図解でわかるWeb技術の仕組み」シリーズ の最終回(第10回)です。
第9回:CORS ― クロスオリジンの壁を理解するも合わせてどうぞ。
1. REST APIとは
RESTの基本概念
REST(Representational State Transfer) とは、Web APIの設計スタイル(アーキテクチャスタイル)です。プロトコルや仕様ではなく、設計の指針 です。
RESTの核心は リソース指向 です。
REST APIで重要な4つのポイント
| 原則 | 意味 |
|---|---|
| 統一インターフェース | HTTPメソッド(GET/POST/PUT/DELETE)で操作を表現する |
| アドレス可能性 | すべてのリソースがURIで一意に識別できる |
| ステートレス | 各リクエストは独立。サーバーにセッション状態を持たない |
| 接続性 | レスポンスに関連リソースへのリンクを含める |
CRUD操作とHTTPメソッドの対応
# 一覧取得
curl -X GET https://api.example.com/v1/users
# 個別取得
curl -X GET https://api.example.com/v1/users/1
# 新規作成
curl -X POST https://api.example.com/v1/users \
-H "Content-Type: application/json" \
-d '{"name": "Taro", "email": "taro@example.com"}'
# 全体更新
curl -X PUT https://api.example.com/v1/users/1 \
-H "Content-Type: application/json" \
-d '{"name": "Taro Yamada", "email": "taro@example.com"}'
# 部分更新
curl -X PATCH https://api.example.com/v1/users/1 \
-H "Content-Type: application/json" \
-d '{"name": "Taro Yamada"}'
# 削除
curl -X DELETE https://api.example.com/v1/users/1
PUT と PATCH の違い
| メソッド | 動作 | 例 |
|---|---|---|
| PUT | リソースを 全体置換 する | 全フィールドを送る必要がある |
| PATCH | リソースの 一部を更新 する | 変更したいフィールドだけ送る |
PUTで一部のフィールドだけ送ると、送らなかったフィールドがnullになる可能性がある
部分更新には PATCH を使いましょう。
2. エンドポイントの命名規則
良いエンドポイントは 見ただけで何ができるかわかる ものです。
ルールのまとめ
| # | ルール | 例 |
|---|---|---|
| 1 | 名詞の複数形を使う | GET /users |
| 2 | ケバブケースを使う | /user-profiles |
| 3 | ネストで親子関係を表現 | /users/{id}/orders |
| 4 | フィルタはクエリパラメータ | /users?role=admin |
| 5 | バージョンをパスに含める | /v1/users |
ネストの具体例
# ユーザー1の注文一覧を取得
curl -X GET https://api.example.com/v1/users/1/orders
# 記事5のコメント一覧を取得
curl -X GET https://api.example.com/v1/articles/5/comments
# 記事5にコメントを追加
curl -X POST https://api.example.com/v1/articles/5/comments \
-H "Content-Type: application/json" \
-d '{"body": "素晴らしい記事です!"}'
フィルタ・ソート・ページネーション
# フィルタ
curl "https://api.example.com/v1/users?role=admin&status=active"
# ソート
curl "https://api.example.com/v1/articles?sort=-created_at"
# ページネーション
curl "https://api.example.com/v1/articles?page=2&per_page=20"
# 組み合わせ
curl "https://api.example.com/v1/articles?tag=javascript&sort=-created_at&page=1&per_page=10"
3. ステータスコードの使い分け
REST APIでは HTTPステータスコードで結果を表現 します。「全部200で返してbodyにエラーコードを入れる」のはアンチパターンです。
実装でよく使うステータスコード
# 201 Created — 新規作成成功時(Location ヘッダーで新リソースのURLを返す)
HTTP/1.1 201 Created
Location: /v1/users/42
Content-Type: application/json
{"data": {"id": 42, "name": "Taro"}}
# 204 No Content — 削除成功時(レスポンスボディなし)
HTTP/1.1 204 No Content
# 422 Unprocessable Entity — バリデーションエラー
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json
{
"errors": [
{"field": "email", "message": "不正なメールアドレス形式です"},
{"field": "name", "message": "名前は必須です"}
]
}
401 vs 403 の使い分け
| コード | 意味 | 具体例 |
|---|---|---|
| 401 | 認証されていない(Who are you?) | トークンなし、期限切れ |
| 403 | 認証済みだが権限不足(I know you, but no.) | 一般ユーザーが管理者APIを呼出 |
4. レスポンス設計のベストプラクティス
エンベロープパターン
レスポンスの構造をAPI全体で統一するのが重要です。
成功レスポンス
{
"data": {
"id": 1,
"name": "Taro",
"email": "taro@example.com"
}
}
一覧レスポンス(ページネーション付き)
{
"data": [
{"id": 1, "name": "Taro"},
{"id": 2, "name": "Hanako"}
],
"meta": {
"total": 100,
"page": 1,
"per_page": 20,
"total_pages": 5
}
}
エラーレスポンス
{
"errors": [
{
"field": "email",
"message": "不正な形式です",
"code": "INVALID_FORMAT"
}
]
}
レスポンス設計のルール
| ルール | 説明 |
|---|---|
data キーにリソースを格納 |
一貫した構造でクライアントの実装を楽にする |
meta キーにメタ情報 |
ページネーション、レート制限情報など |
errors キーにエラー詳細 |
フィールド名 + メッセージ + エラーコード |
| 日付は ISO 8601 | "2026-03-29T10:30:00Z" |
| null ではなく省略 | 値がない場合はキー自体を含めない、または null を明示する(チームで統一) |
5. REST API 設計のべからず集
やってはいけない5つのパターン
1. 全部200で返す
# BAD: エラーなのに200
HTTP/1.1 200 OK
{"error": true, "code": 404, "message": "User not found"}
# GOOD: HTTPステータスコードを正しく使う
HTTP/1.1 404 Not Found
{"errors": [{"message": "User not found"}]}
2. エンドポイントに動詞を入れる
# BAD
POST /createUser
POST /deleteUser
GET /getAllUsers
# GOOD
POST /users
DELETE /users/{id}
GET /users
3. 単数形と複数形が混在する
# BAD
GET /user/1
GET /articles
GET /comment/5
# GOOD(複数形で統一)
GET /users/1
GET /articles
GET /comments/5
4. ネストが深すぎる
# BAD(3階層以上)
GET /users/1/orders/5/items/3/reviews
# GOOD(2階層まで)
GET /users/1/orders
GET /order-items/3/reviews
5. レスポンス形式がバラバラ
エンドポイントごとにJSONの構造が違うと、クライアント側で個別のパーサーが必要になります。data / meta / errors のエンベロープで統一しましょう。
6. まとめ
| 項目 | ポイント |
|---|---|
| REST とは | リソース指向のAPI設計スタイル。HTTPメソッドで操作を表現する |
| エンドポイント | 名詞の複数形 + ケバブケース。動詞は使わない |
| HTTPメソッド | GET(取得)/ POST(作成)/ PUT(全更新)/ PATCH(部分更新)/ DELETE(削除) |
| ステータスコード | 200/201/204/400/401/403/404/422/500 を正しく使い分ける |
| レスポンス設計 | data / meta / errors のエンベロープパターンで統一する |
| べからず | 全部200返し、動詞エンドポイント、深すぎるネスト、形式バラバラ |
シリーズ完結 ― 全10回の振り返り
「図解でわかるWeb技術の仕組み」シリーズ、全10回にお付き合いいただきありがとうございました。
このシリーズで扱ったテーマを振り返ります。
| # | テーマ | 一言まとめ |
|---|---|---|
| 1 | HTTPリクエスト/レスポンス | Web通信の基本単位。メソッド + ヘッダー + ボディ |
| 2 | Cookie・Session・JWT | ステートレスなHTTPに「状態」を持たせる3つの方法 |
| 3 | OAuth 2.0 | 「パスワードを渡さずに権限を委譲する」仕組み |
| 4 | DNS解決 | ドメイン名からIPアドレスを引く階層的な仕組み |
| 5 | HTTPS・TLS | 暗号化・認証・完全性を提供する安全な通信路 |
| 6 | CDN | コンテンツを地理的に近いサーバーから配信する |
| 7 | WebSocket | HTTPの制約を超えた双方向リアルタイム通信 |
| 8 | キャッシュ戦略 | ブラウザ・サーバー・CDNの3層キャッシュ |
| 9 | CORS | クロスオリジンのセキュリティ制御と許可の仕組み |
| 10 | REST API設計 | リソース指向のAPI設計原則とベストプラクティス |
次のステップ
このシリーズでWeb技術の基礎を固めたら、次はこんなテーマに進んでみてください。
- GraphQL ― RESTの課題(Over-fetching / Under-fetching)を解決するクエリ言語
- gRPC ― Protocol Buffersを使った高速なRPC通信
- OpenAPI(Swagger) ― REST APIの仕様書を自動生成する標準フォーマット
- 認証・認可の実装 ― JWT + リフレッシュトークンの実践パターン
- API Gateway ― 認証・レート制限・ルーティングを一元管理するミドルウェア
シリーズ目次
| # | テーマ |
|---|---|
| 1 | HTTPリクエスト/レスポンスの仕組み |
| 2 | Cookie・Session・JWTの違い |
| 3 | OAuth 2.0 の仕組み |
| 4 | DNS解決の流れ |
| 5 | HTTPS・TLS通信の仕組み |
| 6 | CDN の仕組みと役割 |
| 7 | WebSocket ― 双方向リアルタイム通信 |
| 8 | キャッシュ戦略(ブラウザ・サーバー・CDN) |
| 9 | CORS ― クロスオリジンの壁を理解する |
| 10 | REST API 設計の基本原則(この記事) |
「この記事が役に立った」と思ったら、LGTM とストックをお願いします。
シリーズを通してお読みいただいた方は、ぜひ他の記事もストックしてください。
@kotaro_ai_lab
AI活用や開発効率化について発信しています。フォローお気軽にどうぞ!




