API設計書の位置づけ

API設計書はフロントエンド・バックエンド・外部連携先の「接続仕様書」として機能する。実装前にこの設計書でレビューをおこなうことで、実装後の仕様変更コストを最小化できる。

💡 設計書の対象

REST API・GraphQL・gRPC・WebSocket など API の形式を問わず、「外部から呼び出されるインターフェース」であれば設計書の対象となる。本記事では REST API を中心に解説する。

定義すべき項目一覧

分類定義項目必須度
基本情報API名・APIバージョン・ベースURL
基本情報API概要・対象システム
エンドポイントHTTPメソッド・パス
エンドポイント処理概要・対象リソース
認証・認可認証方式(JWT / APIキー / OAuth2)
認証・認可アクセス権限(ロール別)
リクエストパスパラメータ・クエリパラメータ
リクエストリクエストボディ(JSON スキーマ)
リクエストバリデーションルール
レスポンス成功時レスポンス(スキーマ・例)
レスポンスHTTPステータスコード一覧
エラーエラーコード・エラーメッセージ定義
レート制限レートリミット値・超過時の挙動
非機能タイムアウト・レスポンスタイム目標

エンドポイント定義

エンドポイント定義例
■ エンドポイント一覧

No. | HTTPメソッド | パス                        | 処理概要         | 認証
----|-------------|----------------------------|-----------------|------
001 | GET         | /api/v1/users              | ユーザー一覧取得  | JWT
002 | GET         | /api/v1/users/{userId}     | ユーザー詳細取得  | JWT
003 | POST        | /api/v1/users              | ユーザー新規登録  | JWT(ADMIN)
004 | PUT         | /api/v1/users/{userId}     | ユーザー情報更新  | JWT(本人 or ADMIN)
005 | DELETE      | /api/v1/users/{userId}     | ユーザー論理削除  | JWT(ADMIN)
006 | POST        | /api/v1/auth/login         | ログイン         | なし(公開)
007 | POST        | /api/v1/auth/refresh       | トークン更新     | Refresh Token

認証・認可定義

項目仕様
認証方式JWT(Bearer Token)
トークン有効期限アクセストークン: 15分 / リフレッシュトークン: 7日
ヘッダーAuthorization: Bearer <token>
ロール定義ADMIN(全操作)/ USER(自己リソースのみ)/ READONLY(参照のみ)
権限不足時HTTP 403 Forbidden + エラーコード AUTH_003

リクエスト仕様定義

リクエスト仕様例(POST /api/v1/users)
■ パスパラメータ: なし

■ クエリパラメータ: なし

■ リクエストボディ(application/json)
{
  "loginId":    "string  必須  4〜50文字 英数字アンダースコアのみ",
  "email":      "string  必須  RFC5321準拠 最大255文字",
  "password":   "string  必須  8〜72文字 英大小数記号を各1文字以上含む",
  "lastName":   "string  必須  最大50文字",
  "firstName":  "string  必須  最大50文字",
  "roleCode":   "string  必須  ADMIN / USER / READONLY のいずれか"
}

■ リクエスト例
POST /api/v1/users
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

{
  "loginId": "acropolis",
  "email": "acropolis@example.com",
  "password": "P@ssw0rd!",
  "lastName": "山田",
  "firstName": "太郎",
  "roleCode": "USER"
}

レスポンス仕様定義

レスポンス仕様例
■ 成功時(201 Created)
{
  "userId": 12345,
  "loginId": "acropolis",
  "email": "acropolis@example.com",
  "lastName": "山田",
  "firstName": "太郎",
  "roleCode": "USER",
  "createdAt": "2026-06-18T12:00:00+09:00",
  "updatedAt": "2026-06-18T12:00:00+09:00"
}

■ HTTPステータスコード一覧
200 OK          — 取得・更新成功
201 Created     — 新規作成成功
204 No Content  — 削除成功
400 Bad Request — バリデーションエラー
401 Unauthorized— 認証エラー(トークン未提供・期限切れ)
403 Forbidden   — 認可エラー(権限不足)
404 Not Found   — リソースなし
409 Conflict    — 重複エラー(loginId が既存)
500 Internal    — サーバー内部エラー

エラーコード定義

エラーコードHTTPメッセージ発生条件
AUTH_001401認証トークンが必要ですAuthorization ヘッダー未提供
AUTH_002401トークンの有効期限が切れていますJWT 期限切れ
AUTH_003403この操作を行う権限がありませんロール不足
VAL_001400必須項目が未入力です必須フィールド欠如
VAL_002400入力形式が正しくありません型・フォーマットエラー
DUP_001409ログインIDが既に使用されていますloginId 重複

Python Tips — FastAPI から OpenAPI 仕様を自動抽出

FastAPI アプリケーションが稼働している環境では、/openapi.json から仕様を取得してドキュメント化できる。

Python — OpenAPI 仕様の取得とエンドポイント一覧生成
"""
FastAPI / Spring Boot などの /openapi.json からエンドポイント一覧を取得し
Markdown テーブルとして出力する
pip install requests
"""
import json, requests

OPENAPI_URL = "http://localhost:8080/openapi.json"  # 環境に合わせて変更

def fetch_openapi(url: str) -> dict:
    resp = requests.get(url, timeout=10)
    resp.raise_for_status()
    return resp.json()

def extract_endpoints(spec: dict) -> list[dict]:
    rows = []
    for path, methods in spec.get("paths", {}).items():
        for method, op in methods.items():
            if method in ("get", "post", "put", "patch", "delete"):
                security = op.get("security", [])
                auth = "なし" if not security else list(security[0].keys())[0] if security else "不明"
                rows.append({
                    "method": method.upper(),
                    "path": path,
                    "summary": op.get("summary", "—"),
                    "tags": ", ".join(op.get("tags", [])),
                    "auth": auth,
                })
    return rows

def to_markdown(rows: list[dict]) -> str:
    header = "| Method | Path | Summary | Tags | Auth |"
    sep    = "|--------|------|---------|------|------|"
    lines  = [header, sep]
    for r in rows:
        lines.append(f"| {r['method']} | `{r['path']}` | {r['summary']} | {r['tags']} | {r['auth']} |")
    return "
".join(lines)

try:
    spec = fetch_openapi(OPENAPI_URL)
    rows = extract_endpoints(spec)
    print(f"# API エンドポイント一覧 ({len(rows)} 件)")
    print(to_markdown(rows))
    # JSON ファイルにも保存
    with open("api_spec_extracted.json", "w", encoding="utf-8") as f:
        json.dump(rows, f, ensure_ascii=False, indent=2)
    print("\n✅ api_spec_extracted.json に保存しました")
except Exception as e:
    print(f"❌ 取得失敗: {e}")

レビューチェックリスト

#チェック項目
1全エンドポイントにHTTPメソッドとパスが定義されているか
2認証・認可方式が全エンドポイントに定義されているか
3リクエストの必須/任意・型・バリデーションが定義されているか
4レスポンスのスキーマと具体例が定義されているか
5エラーコードとエラーメッセージが定義されているか
6APIバージョン管理方針が定義されているか
7レートリミットが定義されているか