メインコンテンツへ移動
SEMentor

良いREST API設計の原則——SE が知っておくべき10のルール

2026年4月25日 約9分で読める

後悔しないAPI設計のために。命名・バージョニング・エラー設計など実務で通用する原則を体系化する

API はチームとの「契約」

API は内部実装の詳細を隠しつつ、クライアントとの**インターフェース(契約)**を提供します。一度公開した API の破壊的変更は、使っているクライアントをすべて壊します。

だからこそ、設計段階で十分に考える価値があります。

ルール 1:リソース名は名詞・複数形

✅ GET /users
✅ GET /users/123
✅ POST /orders
✅ DELETE /products/456

❌ GET /getUser
❌ POST /createOrder
❌ DELETE /deleteProduct?id=456

動詞はメソッド(GET/POST/PUT/DELETE)が担います。URI はリソースを表す名詞にします。

ルール 2:HTTP メソッドを正しく使う

メソッド操作べき等か
GET取得GET /users/123
POST作成POST /users
PUT全体更新PUT /users/123
PATCH部分更新PATCH /users/123
DELETE削除DELETE /users/123

べき等(idempotent):同じリクエストを何度送っても結果が変わらない性質。GET/PUT/DELETE はべき等、POST は毎回新しいリソースを作るので非べき等。

ルール 3:適切な HTTP ステータスコードを返す

2xx 成功
  200 OK          — GET / PUT / DELETE 成功
  201 Created     — POST でリソース作成成功(Location ヘッダも返す)
  204 No Content  — 成功だが返すボディがない(DELETE など)

4xx クライアントエラー
  400 Bad Request    — リクエストの形式・バリデーションエラー
  401 Unauthorized   — 未認証(ログインしていない)
  403 Forbidden      — 認証済みだが権限なし
  404 Not Found      — リソースが存在しない
  409 Conflict       — 競合(例:すでに存在するメールアドレス)
  422 Unprocessable  — バリデーションエラー(詳細を body に)

5xx サーバーエラー
  500 Internal Server Error — サーバー側のバグ
  503 Service Unavailable   — 一時的な障害
// 400 エラーのレスポンス例
{
  "error": {
    "code": "VALIDATION_FAILED",
    "message": "バリデーションエラーが発生しました",
    "details": [
      { "field": "email", "message": "メールアドレスの形式が正しくありません" },
      { "field": "age", "message": "18歳以上を入力してください" }
    ]
  }
}

ルール 4:一貫したレスポンス構造

エンドポイントごとにレスポンス構造がバラバラだとクライアントの実装コストが上がります。

// 単一リソース
{
  "data": {
    "id": 123,
    "name": "田中太郎",
    "email": "tanaka@example.com",
    "createdAt": "2026-04-25T10:00:00Z"
  }
}

// コレクション(ページネーション付き)
{
  "data": [...],
  "meta": {
    "total": 1543,
    "page": 1,
    "perPage": 20,
    "totalPages": 78
  }
}

ルール 5:ネストは 2 階層まで

✅ GET /users/123/orders
✅ GET /orders/456/items

❌ GET /users/123/orders/456/items/789/reviews
→ GET /items/789/reviews に分解

深すぎるネストは URL が脆くなり、変更に弱くなります。

ルール 6:フィルタ・ソート・ページネーションはクエリパラメータ

GET /products?category=electronics&minPrice=10000&sortBy=price&order=asc&page=2&perPage=20

これらをパスに入れるのは NG です。

❌ GET /products/electronics/sort-by-price/page-2

ルール 7:日時は ISO 8601・タイムゾーン付き

// ✅ UTC で統一
"createdAt": "2026-04-25T10:00:00Z"

// ❌ タイムゾーン不明
"createdAt": "2026/04/25 10:00:00"

サーバーは UTC で管理し、表示はクライアント側でローカル変換します。

ルール 8:バージョニング戦略を最初に決める

# URLパス方式(最もシンプル・推奨)
GET /v1/users
GET /v2/users

# ヘッダ方式(URLが汚れない)
GET /users
Accept: application/vnd.myapi.v2+json

バージョニングは最初から設計に含めます。後からの追加は難しい。

破壊的変更(フィールド削除・型変更・必須化)は必ず新バージョンに。

ルール 9:認証には Bearer トークン

GET /users/me HTTP/1.1
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
  • Cookie 認証は CSRF リスクあり(API には不向き)
  • Basic 認証は毎回認証情報を送信するので NG
  • JWT の場合はペイロードに機密情報を入れない(Base64 は暗号化ではない)

ルール 10:API ドキュメントは OpenAPI で自動生成

# openapi.yaml
openapi: 3.0.0
info:
  title: My API
  version: "1.0"
paths:
  /users/{id}:
    get:
      summary: ユーザー取得
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: 成功

コードファーストなら swagger-jsdoc、スキーマファーストなら OpenAPI Generator でクライアント SDK を自動生成できます。

まとめ

ルールポイント
1. 名詞・複数形/users, /orders
2. メソッドを正しくGET=取得, POST=作成, PUT=更新, DELETE=削除
3. ステータスコード200/201/400/401/403/404/422/500
4. 一貫した構造{ "data": ... } + ページネーション
5. ネストは 2 階層/users/123/orders まで
6. フィルタはクエリパラメータ?page=2&sortBy=price
7. UTC で管理2026-04-25T10:00:00Z
8. バージョニング/v1/, /v2/ を最初から
9. Bearer 認証JWT + Authorization ヘッダ
10. OpenAPIドキュメントを自動生成

API の品質はその API を使うすべてのクライアントの品質に直結します。最初の設計に時間をかける価値は十分にあります。

この記事はいかがでしたか?

記事一覧へ