RESTful APIを設計する
概要
- 日程: Day 3 / セッション 8
- 時間: [15:00-15:30]
- 形式: 実習
- ゴール: 自分の機能一覧をもとに(条件)、リソース・HTTPメソッド・JSONレスポンス例を含むRESTful API設計書を作成できる(行動)(エンドポイント5本以上、選択理由つき)(基準)
- 学習形式: ハンズオン実習(AIサポートあり)
導入(5分)
前のセッションで、UIと機能の通信の主流がREST/JSONであることを学びました。今度はそれを自分の手で設計します。
ここで問いかけです。Day 2 であなたは状態遷移からCRUDの機能一覧を導出しました。CRUDは Create・Read・Update・Delete。一方、HTTPの主なメソッドは POST・GET・PUT・DELETE。……何か気づきませんか?
そうです。情報モデルのCRUDと、RESTのHTTPメソッドは、そのまま1対1に対応します。 つまり、あなたの機能一覧はすでにAPI設計の下書きなのです。Day 1 の情報定義書からここまで積み上げてきた成果物が、一直線に実装へつながる瞬間です。
このセッションで作るRESTful API設計書は、明日 Day 4 でそのまま実装する設計図です。この設計書の精度が、明日の実装速度を決めます。 30分の短い実習ですが、集中して仕上げましょう。
本編(20-40分)
1. CRUD=RESTメソッド 機能一覧をAPIに写し取る
RESTの設計は、次の2ステップだけです。
- 情報モデルをリソース(URLで指せるもの)にする
- CRUDをHTTPメソッドに割り当てる
対応表はこれだけです。暗記ではなく「同じものの別名」として見てください。
| CRUD | HTTPメソッド | 家計簿の機能一覧での例 |
|---|---|---|
| Create | POST | 支出記録の新規入力 |
| Read | GET | 支出記録の1件表示・一覧表示 |
| Update | PUT / PATCH | 支出記録の更新 |
| Delete | DELETE | 支出記録の削除 |
これは翻訳のようなものです。日本語(機能一覧)を英語(API)に訳すとき、意味は変えず表記だけ変える。「支出記録の新規入力」という機能は POST /expenses という1行に訳されます。
UpdateにPUTとPATCHの2つがあるのは、全体を置き換えるか(PUT)、一部だけ直すか(PATCH)の違いです。迷ったら、この研修ではPUTで統一して構いません。
ここで少し考えてみてください。あなたの機能一覧に「検索」や「月別集計」があった場合、どのメソッドになるでしょうか? Day 2 で「検索は条件付きのRead」と学びました。だからGETです。GET /expenses?month=2026-07 のように、条件はURLの後ろ(クエリパラメータ)に付けます。
コード例・実例
Day 2 の機能一覧(支出記録)が、そのままエンドポイントに翻訳される様子です。
| 機能一覧(Day 2の成果物) | CRUD | エンドポイント |
|---|---|---|
| 支出記録の新規入力 | Create | POST /expenses |
| 支出記録の一覧表示 | Read | GET /expenses |
| 支出記録の1件表示 | Read | GET /expenses/{id} |
| 支出記録の更新 | Update | PUT /expenses/{id} |
| 支出記録の削除 | Delete | DELETE /expenses/{id} |
{id} は「何件目か」を指す番号です。一覧はリソースの集合(/expenses)、1件は集合の中の個体(/expenses/1)を指します。
ここがポイント
- 機能一覧の1行がエンドポイント1本に対応する。だからエンドポイントの抜け漏れは機能一覧で検出できる(トレーサビリティ)
- URLに入れるのは名詞(リソース)だけ。動詞はHTTPメソッドが担当する
- リソース名は複数形の名詞(expenses)が慣例。情報モデル名がそのまま候補になる
コラム
HTTPメソッドには「安全性」と「冪等性(べきとうせい)」という性質があります。GETは安全(何度呼んでもデータが変わらない)、PUTとDELETEは冪等(1回でも100回でも結果が同じ)、POSTはどちらでもありません。だからブラウザは、POSTの後にリロードすると「再送信しますか?」と警告してくるのです。あれは「POSTは2回呼ぶと2件登録されてしまう」ことを知っているからです。通販サイトで「注文ボタンを2度押さないでください」と書かれているのも同じ理由です。逆に言えば、DELETEを2回送っても「削除済みのものを削除」で結果は変わりません。この性質を知っていると、通信エラー時に「もう一度送ってよいか」を理屈で判断できるようになります。
2. 家計簿システムのRESTful API設計書 完成例
家計簿システムの設計書を通しで見せます。あなたはこの後、自分のテーマで同じものを作ります。
ステップ1: リソース設計(情報モデル→リソース)
- 支出記録 →
/expenses、/expenses/{id} - カテゴリ →
/categories
ステップ2: エンドポイント表
| No. | メソッド | パス | 機能 | 主なレスポンス |
|---|---|---|---|---|
| 1 | GET | /expenses | 支出記録の一覧表示 | 200 OK |
| 2 | GET | /expenses/{id} | 支出記録の1件表示 | 200 OK |
| 3 | POST | /expenses | 支出記録の新規入力 | 201 Created |
| 4 | PUT | /expenses/{id} | 支出記録の更新 | 200 OK |
| 5 | DELETE | /expenses/{id} | 支出記録の削除 | 204 No Content |
| 6 | GET | /categories | カテゴリの一覧表示 | 200 OK |
ステップ3: JSONレスポンス・リクエスト例
GET /expenses のレスポンス例。属性は Day 2 の情報モデル(日付・金額・カテゴリ・メモ)そのままです。
{
"expenses": [
{ "id": 1, "date": "2026-07-06", "amount": 480, "category": "食費", "memo": "コーヒー" },
{ "id": 2, "date": "2026-07-06", "amount": 1200, "category": "交際費", "memo": "ランチ会" }
]
}
POST /expenses のリクエストボディ例(idはサーバが採番するので送らない)。
{ "date": "2026-07-07", "amount": 350, "category": "食費", "memo": "パン" }
良いURIと悪いURIの対比も押さえましょう。GET /expenses はRESTfulに該当しますが、GET /getExpenseList は該当しません。なぜなら、URLに動詞(get)が入っており、操作の表現がメソッドと二重になっているからです。動詞はメソッドに任せる、URLは名詞だけ。これがRESTの作法です。
| 悪い例(RPC風) | 良い例(RESTful) |
|---|---|
| GET /getExpenseList | GET /expenses |
| POST /createExpense | POST /expenses |
| POST /deleteExpense?id=1 | DELETE /expenses/1 |
ここで分からないことがあれば、AIに質問してみましょう。「なぜ削除をPOSTで書いてはいけないの?」と聞くと、冪等性の観点から説明してくれるはずです。
コード例・実例
設計書はMarkdownの表とJSONコードブロックで書けば十分です。上のステップ1〜3の形式が、そのまま今日の成果物のテンプレートになります。
ここがポイント
- ステータスコードは最低3つ覚える: 200(成功)、201(作成成功)、404(見つからない)
- レスポンスJSONの属性名は、情報モデルの属性名と一致させる。ここがずれるとDay 4で混乱する
- 設計書に「なぜこのリソース分割にしたか」を一文添えると、Day 3の成果物基準(選択理由)を満たせる
コラム
RESTが論文発表された2000年当時、「RESTful API」という言葉はまだ存在しませんでした。流れを変えたのは企業です。2000年にeBay、2002年にAmazonが自社機能をWeb APIとして外部公開し、2006年にはTwitter APIを使った外部アプリが本家より人気になる現象が起きました。「APIを公開すると、他社が勝手に自社サービスを拡張してくれる」という発見はAPIエコノミーと呼ばれ、いまや地図も決済も認証も、他社APIの組み合わせでサービスが作れる時代です。あなたが今日書く設計書は、その世界共通の「サービスの取扱説明書」の書き方そのものです。就職後、最初に読まされる社内文書がAPI設計書だった、という先輩は少なくありません。
💬 AIに聞いてみよう
- 「PUTとPATCHの使い分けを、家計簿の支出記録の更新を例に説明してください」
- 「『予算』のような、月に1件しか存在しないリソースのURI設計はどうすべきですか? /budgets/{yyyy-mm} のような形は適切ですか?」
- 「REST APIのエラーレスポンス(404や400)のJSONボディには何を入れるのが慣例ですか? 例を見せてください」
実習・演習
課題
自分の開発テーマのRESTful API設計書を作成してください。手順は家計簿の例と同じです。
- リソース抽出(5分): Day 2 の情報モデル一覧からリソース名(複数形の名詞)を決める
- エンドポイント表(10分): 機能一覧の各行をメソッド+パスに翻訳する。エンドポイント5本以上
- JSON例(7分): 一覧GETのレスポンス例と、POSTのリクエストボディ例を最低1組書く。属性は情報モデルと一致させる
- AIレビュー(残り時間): 下のプロンプト例でAIにレビューさせ、指摘を1つ以上反映する
まず自分で書き切ってから、AIレビューに進んでください。順序が逆になると、自分の理解の穴が見えなくなります。
成果物
- RESTful API設計書(Markdown推奨)
- リソース設計(情報モデルとの対応、分割理由を一文)
- エンドポイント表(5本以上、メソッド・パス・機能・レスポンスコード)
- JSONレスポンス例とリクエストボディ例(各1つ以上)
- これはDay 3の成果物であり、Day 4の実装の設計図です
ヒント
- エンドポイントが5本に届かないときは、2つ目の情報モデル(家計簿ならカテゴリや予算)を思い出す。主要モデル1つで5本+副モデルのGETで6本が定番の形
- URLに動詞が入っていたら赤信号。名詞に直し、動詞をメソッドに移す
- 詰まったら、そのままAIに相談しましょう。コピペで使えるプロンプト例:
私の開発テーマは「◯◯」です。以下は私の機能一覧です。
(ここに機能一覧を貼る)
これをRESTful APIのエンドポイント表(メソッド・パス・機能)に翻訳してください。
ただし答えを丸写しにしたくないので、まず最初の2本だけ例を示し、
残りは私が書いたものを添削する形で進めてください。
私のRESTful API設計書をレビューしてください。
(ここに設計書を貼る)
RESTの原則から外れている点(URLに動詞がある、メソッドの誤用、
ステータスコードの誤り、属性名が情報モデルとずれている等)を
優先度順に指摘してください。
あなたはこのAPIを使うフロントエンド開発者です。
(ここに設計書を貼る)
一覧画面と登録フォームを実装する立場から、使いにくい点・
情報が足りない点を挙げてください。
まとめ(5分)
今回学んだことを一言でまとめると、**「情報モデルのCRUDはRESTのメソッドにそのまま翻訳でき、機能一覧はAPI設計書の下書きである」**です。
- Create=POST、Read=GET、Update=PUT/PATCH、Delete=DELETE の対応が設計の核
- URLは名詞(リソース)、動詞はメソッドに任せる。/getExpenseList はRESTfulではない
- 設計書のJSON属性は情報モデルと一致させ、Day 1〜3の成果物を一本の線でつなぐ
これで、Day 4 の実装に必要な設計図がそろいました。次のセッションはDay 3の最後、「開発手法はなぜ複数あるのか」を考え、今日1日の学びをAIに説明して締めくくります。
🔄 振り返りチェック
- あなたのエンドポイント表の各行は、Day 2 の機能一覧のどの行に対応しますか? 対応しない行はありませんか?
- 「POST /deleteExpense」がRESTfulでない理由を、メソッドと名詞・動詞の観点で説明できますか?
- あなたのJSONレスポンス例の属性名は、情報モデルの属性名と一致していますか?
補足資料
- 参考リンク: MDN Web Docs「HTTP リクエストメソッド」(https://developer.mozilla.org/ja/docs/Web/HTTP/Methods)
- 参考リンク: OpenAPI Specification(https://spec.openapis.org/oas/latest.html)※実務でのAPI設計書の標準形式
- 発展課題: 自分のAPI設計書に「エラーレスポンス(400/404)のJSON例」と「ページネーション(?page=2)」を追加し、AIにレビューさせてみる
学習ガイド
想定される質問と回答例
| 質問 | ヒント |
|---|---|
| ログインや検索はどのエンドポイントになりますか? | 検索はGET /expenses?keyword=◯◯(条件付きRead)。ログインは「セッション」や「トークン」というリソースのPOSTと考えられるが、今回の必須範囲外なので余裕があれば、と案内する |
| 一覧と1件表示はなぜ別エンドポイントなのですか? | 指すリソースが違う。/expensesは集合、/expenses/{id}は個体。Day 2 でReadを一覧・1件の2機能に分けたことと同じ対応 |
| PUTとPATCHはどちらを書けばよいですか? | 全体置き換えがPUT、部分修正がPATCH。この研修ではPUTに統一してよい。迷って手が止まる方が損と伝える |
| エンドポイントが5本を超えて増えすぎました | 情報モデル1つにつきCRUD由来の5本が基本形。それ以外の本数はまず「どの情報モデルのCRUDか」で説明できるか確認し、説明できないものは保留にする |
つまずきやすいポイント
| つまずきポイント | ヒント |
|---|---|
| URLに動詞を入れてしまう(/getExpenseList型) | 「URLは名詞、動詞はメソッド」と唱えて全行を点検する。動詞が消せないときは、隠れたリソース(例: /search→検索条件付きGET /expenses)に言い換える |
| JSONの属性名が情報モデルとずれる | 情報モデル図を横に置いて転記する。ここがずれるとDay 4で画面表示のたびに変換コードが必要になり、実装速度が落ちると理由ごと伝える |
| メソッドとステータスコードの組み合わせを丸暗記しようとする | 覚えるのは3つだけ(200成功・201作成・404なし)でよい。残りは必要になったときにAIに聞けば十分と伝え、手を動かす時間を優先する |
| 機能一覧を見ずにゼロからAPIを考えてしまう | 必ず機能一覧からの「翻訳」で作る。ゼロ発想は抜け漏れのもと。Day 2 の成果物を開いてから書き始める習慣をつける |