📄
概念 📚 beginner-stepup

REST API 仕様書の書き方(Month 2 Week 7)

エンドポイント一覧・リクエスト/レスポンススキーマ・ステータスコード設計を OpenAPI 形式と Markdown 形式で書く方法

ER 図でデータ構造が決まったら、次は フロントとバックの契約 である API 仕様書を書きます。これが Month 3-4 の実装のベースになります。


なぜ API 仕様書を先に書くのか

Month 3(フロント)と Month 4(バック)を並行して進められるようにするためです。仕様書があれば:

  • フロント側は仕様書を見てモック API を組み、UI を実装できる
  • バック側は仕様書を見てエンドポイントを実装できる
  • 両者が結合する時に「あれ、リクエスト形式が違う」という事故が減る

小規模プロジェクトでも 30 分で API 仕様書を書く習慣 は必ず報われます。


最小限の仕様書フォーマット(Markdown)

OpenAPI を書き始める前に、まず Markdown で以下の 5 項目を埋めます。

1. エンドポイント一覧

MethodPath用途認証
GET/posts投稿一覧不要
GET/posts/:id投稿詳細不要
POST/posts投稿作成必要
DELETE/posts/:id投稿削除必要(作成者のみ)
POST/auth/registerユーザー登録不要
POST/auth/loginログイン不要

2. エンドポイントごとの詳細

各エンドポイントを以下のテンプレで書きます。

## POST /posts

投稿を作成する。

### 認証
Bearer token 必須

### Request body
{
  "content": string (1〜280 文字)
}

### Response (201 Created)
{
  "id": string (UUID),
  "content": string,
  "authorId": string (UUID),
  "createdAt": string (ISO 8601)
}

### Error
- 400: バリデーション失敗(文字数違反)
- 401: 未認証

3. ステータスコードの方針

コード使う場面
200GET 成功
201POST で新規作成成功
204DELETE / PUT で成功(ボディなし)
400バリデーション失敗(クライアント入力が悪い)
401認証が必要 or トークンが無効
403認証は通ったが権限がない
404リソースが存在しない
409競合(重複登録など)
500サーバー内部エラー

よくある迷い: 「無効な投稿 ID を渡された」→ 400 ではなく 404 を返す。ID の形式自体がおかしいなら 400、形式は正しいが存在しないなら 404。

4. 共通レスポンス形式

エラーレスポンスは形を統一します。

{
  "error": "VALIDATION_FAILED",
  "message": "content must be between 1 and 280 characters",
  "details": {
    "field": "content",
    "value": ""
  }
}
  • error: 固定のエラーコード(フロント側で分岐に使う)
  • message: 英語の人間向け説明(ログに残す)
  • details: 任意の追加情報

5. 認証方式

Bearer token(JWT)を Authorization ヘッダで送る:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6Ikp...

詳細は b07-auth-patterns 参照。


OpenAPI 形式で書く(上級)

Markdown で書き慣れたら、OpenAPI(Swagger)形式に昇格させると自動テスト・モック生成・クライアント SDK 生成の恩恵を受けられます。

openapi: 3.0.3
info:
  title: SNS clone API
  version: 1.0.0
servers:
  - url: http://localhost:3001
    description: ローカル開発
  - url: https://api.example.cloudfront.net
    description: 本番

paths:
  /posts:
    get:
      summary: 投稿一覧を取得
      responses:
        '200':
          description: 成功
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Post'
    post:
      summary: 投稿を作成
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [content]
              properties:
                content:
                  type: string
                  minLength: 1
                  maxLength: 280
      responses:
        '201':
          description: 作成成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Post'
        '400':
          $ref: '#/components/responses/ValidationError'
        '401':
          $ref: '#/components/responses/Unauthorized'

components:
  schemas:
    Post:
      type: object
      required: [id, content, authorId, createdAt]
      properties:
        id:
          type: string
          format: uuid
        content:
          type: string
        authorId:
          type: string
          format: uuid
        createdAt:
          type: string
          format: date-time
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

OpenAPI を書くメリット

  • Swagger UI で仕様書が自動 HTML 化される(https://editor.swagger.io/ に貼ると即プレビュー)
  • Zod schema を自動生成できる(openapi-typescript などのツール)
  • モックサーバーが立つ(prism などで実 API なしにフロント開発)

Month 2 では Markdown で十分、Month 3 以降に必要を感じたら OpenAPI に昇格で OK です。


設計の原則

RESTful な URL 設計

  • 名詞で書く(動詞は HTTP メソッドが担う)
  • 複数形(リソースは集合として捉える)
  • 階層は浅く(深くても 2 階層まで)
良い例悪い例
GET /posts/:idGET /getPostById?id=xxx
POST /postsPOST /createPost
GET /users/:id/postsGET /posts_of_user?userId=xxx
DELETE /posts/:id/reactionsPOST /removeReaction

べき等性(idempotent)

同じリクエストを何度送っても結果が変わらない操作は PUT / DELETE / GET。変わるのは POST のみ。


Week 7 のアウトプット

  • ☐ エンドポイント一覧表が埋まっている
  • ☐ 各エンドポイントに Request body / Response body / エラーコードが書かれている
  • ☐ 共通エラーレスポンス形式が決まっている
  • ☐ 認証方式が書かれている
  • docs/api-spec.md として PR 提出

よくある失敗

  • 同じような意味で違う表記: 「userId」と「user_id」が混在、「postId」と「post_id」が混在。最初にルール化(本カリキュラムは camelCase 推奨)
  • エラー時のレスポンスが未定義: 成功時だけ仕様書に書いて、エラー時を書かないとフロントで分岐できません
  • 実装と仕様のズレを放置: 実装が変わったら仕様書も更新。仕様書が古くなると誰も見なくなります

参考

生きているコード

本ドキュメントで扱ったパターンの完全な動作コードは、メンター側リポジトリの参照ブランチで確認できます。

  • 対応 Week: W7
  • 参照ブランチ:
  • W7: reference/week-7
  • 対応 checklist 項目: (直接対応なし)

ブランチの作り方・見方は b00-curriculum-map を参照してください。

📚 beginner-stepup 全 53 章
導入編 13 章
  1. 1. 📄Web とは何か
  2. 2. 📄URL を打ってから画面が表示されるまで
  3. 3. 📄ネットワーク基礎(TCP/IP・DNS・HTTPS)
  4. 4. 📄【発展】物理層から通信が成立するまで(電力・Ethernet・Wi-Fi・Bluetooth)
  5. 5. 📄WSL2・Docker セットアップ詳細(Windows 向け)
  6. 6. 📄環境構築の段階的導入(macOS / Windows)
  7. 7. 📄カリキュラム全体マップ(Week × 教材 × 参照ブランチ × 要求チェックリスト)
  8. 8. 📄このカリキュラムの使い方(SQL・Python・Dify経験者向け)
  9. 9. 📄シェル・ターミナル基礎
  10. 10. 📄Windows で完全にゼロから始める開発環境構築(Week 1)
  11. 11. 📄Git基礎
  12. 12. 📄GitHubワークフロー
  13. 13. 📄パッケージ管理(pnpm workspace)
応用編 16 章
  1. 1. 📄AWSインフラ基礎
  2. 2. 📄AWS Budget Alert の設定(Month 5 Week 17)
  3. 3. 📄環境変数管理
  4. 4. 📄Bastion EC2 と SSH ProxyJump(Month 5 Week 18)
  5. 5. 📄CI/CD基礎
  6. 6. 📄ECR への Docker イメージ push と App EC2 デプロイ(Month 5 Week 19)
  7. 7. 📄テスト設計の基本
  8. 8. 📄CloudFront + S3 + ALB で公開する(Month 5 Week 20)
  9. 9. 📄CLAUDE.md・プロジェクト設定
  10. 10. 📄PR レビュー 5 観点ルーブリック(全 Week 共通)
  11. 11. 📄タスク分解・仕様の書き方
  12. 12. 📄Playwright で E2E テスト(Month 6 Week 22)
  13. 13. 📄生成コードのレビュー・デバッグの勘所
  14. 14. 📄Trivy で脆弱性スキャン(Month 6 Week 23)
  15. 15. 📄CloudWatch Logs の読み方と運用(Month 6 Week 23)
  16. 16. 📄PDF ポートフォリオの自動生成(Month 6 Week 24)