第07章:部:テスト・観測・実務運用(23〜24章)🧪👀✅
この章のゴール🎯✨
- GET / PUT / DELETE が「なぜ冪等にしやすいのか」を、言葉で説明できる🙂
- 「冪等っぽいけど実は危ない実装」を見抜ける👀⚠️
- ミニ注文APIで、冪等なふるまいのコードが書ける🧑💻💕

まずここだけ覚えよう💡(Safe と Idempotent 🚦)
HTTPの公式仕様(RFC 9110)では、
- Safe(安全):基本「読み取り専用」=サーバー状態を変えない想定📖
- Idempotent(冪等):同じリクエストを何回送っても、サーバーへの“意図された効果”が同じ🔁
と定義されているよ📚✨ (rfc-editor.org)
そして、仕様上はこう👇
- GET / HEAD / OPTIONS / TRACE は Safe(=冪等でもある) (rfc-editor.org)
- PUT と DELETE は Safe じゃないけど冪等 (rfc-editor.org)
🌟ポイント:冪等だと「通信が怪しくて再送しても、壊れにくい」から超重要! 仕様でも「通信失敗時に自動リトライしやすい」ことが理由として書かれてるよ🔁 (rfc-editor.org)
1) GET は「読むだけ」だから冪等🫶👀
GET の意味(ざっくり)
GET は「そのリソースの表現(データ)をください」っていうメソッド📦 (MDNウェブドキュメント) なので普通は 何回 GET してもデータを読むだけ=冪等&Safe になりやすいよ✨ (rfc-editor.org)
✅ 良い例(注文の参照)📦
-
GET /orders/ord_001- ord_001 の注文を返すだけ
- 10回押しても「読むだけ」🙂🔁
⚠️ 落とし穴(GET で状態を変える)😱
仕様でも「Safe に見えるけど、実装が危険なことはある」と注意されてるよ⚠️ (rfc-editor.org)
たとえば👇
GET /orders/ord_001/confirmみたいに **GET で“確定”**させる(アウト!)💥GETするたびに「ポイント付与」「決済」「在庫減らす」みたいな副作用(超アウト!)💳📦
🧠コツ:GET は “何があっても読むだけ” に寄せると設計がキレイ✨
2) PUT は「置き換え」だから冪等にしやすい🔁🧱
PUT の意味(超大事!)
PUT は 「対象リソースを、この内容で丸ごと置き換える」 が基本✨ (MDNウェブドキュメント) つまり「同じIDに、同じ内容を PUT」すると、結果は毎回同じになりやすい=冪等🥰
✅ 良い例(注文を“この形にする”)🧾
PUT /orders/ord_001- body:
{ ...注文の完成形... }
これを2回送っても、サーバーの注文は「その形」になるだけ🔁✨
⚠️ PUT を壊す典型パターン(実は“足し算”)🚫➕
PUT なのに中身がこうなってると危険👇
- 「毎回、明細行を1行追加する」
- 「履歴テーブルに毎回“新規レコード”を追加する(それが仕様上の効果)」
- 「毎回 updatedAt を必ず更新して“別状態”にしてしまう」⏱️😵
冪等の定義は「意図された効果が同じ」だから、リクエストが同じなのに状態が変わり続けるなら、あなたのAPIは冪等じゃなくなるよ⚠️ (rfc-editor.org)
🌸やり方:PUT は「結果の形を指定する」 ❌「追加する」系は PUT でやらない(やるなら設計を工夫する)
🌟 PUT の“あるある”Q&A
Q:PUT で、存在しないIDに送ったら?
A:仕様上は「作る」使い方もありえるよ(サーバー設計次第)🙂
初回は 201、2回目は 200 でも、状態が同じなら冪等だよ👌✨
3) DELETE は「消す」だから冪等にしやすい🗑️🔁
DELETE の意味
DELETE は「そのリソースを削除する」💥 (MDNウェブドキュメント) 削除って、2回やっても最終状態は「消えてる」だから冪等にしやすい🥰 (rfc-editor.org)
✅ 良い例(注文の削除)
-
DELETE /orders/ord_001- 1回目:消える
- 2回目:もう無い(でも“無い状態”は同じ)🔁
🤔 2回目は 404? 204?
どっちでも設計としてはよくあるよ🙂
- 常に 204(No Content):クライアントがシンプル✨
- 無ければ 404:状態を厳密に返す
どちらでも「最終状態が同じ(存在しない)」なら、冪等の考え方と相性はいいよ🫶
⚠️ DELETE を壊す典型パターン(“二重取り消し”)😱
- DELETE のたびに「返金を実行」💳💥
- DELETE のたびに「在庫を戻す」📦↩️
- DELETE のたびに「ポイントを戻す」🎫↩️
こういう“外部効果”があるなら、DELETEを“消すだけ”にせず、設計を分ける(例:取消の状態遷移を作る)ほうが安全だよ⚔️✨
ちょい寄り道:POST/PATCH はなぜ別扱い?🚧
MDN でも「POST と PATCH は、冪等が保証されない」って整理されてるよ📚 (MDNウェブドキュメント)
- POST:だいたい「作成」=増える=連打で増えやすい😵
- PATCH:部分更新だけど、内容によっては「加算」になって冪等じゃないことがある⚠️
🌟ただし「設計で冪等にする」ことは可能(冪等キー方式など)だけど、それは後半でガッツリやるよ🔑✨
ミニ注文APIで体感しよう🍰🧑💻
例のデータ型(超ミニ)🧩
type OrderId = string;
type Order = {
id: OrderId;
userId: string;
amount: number; // 合計金額(仮)
status: "draft" | "confirmed";
};
// 超ミニなインメモリDB
const orders = new Map<OrderId, Order>();
GET:読むだけ(冪等&Safe)👀🔁
function getOrder(id: OrderId): Order | null {
return orders.get(id) ?? null;
}
PUT:「この形にする」(冪等にしやすい)🧱🔁
function putOrder(id: OrderId, body: Omit<Order, "id">): Order {
// 「置き換え」なので set 一発が分かりやすい
const order: Order = { id, ...body };
orders.set(id, order);
return order;
}
✅ これなら、同じ id と同じ body を2回送っても、Map の中身は同じだよ🔁✨
DELETE:「存在しない状態にする」(冪等にしやすい)🗑️🔁
function deleteOrder(id: OrderId): void {
// すでに無くても、最終状態は「無い」で同じ
orders.delete(id);
}
演習コーナー✍️🧠(手を動かすと最速で理解できるよ!)
演習1:PUT で冪等になる例を書こう🧾🔁
PUT /orders/ord_001の body を考える- 同じものを2回送ったら、注文の状態はどうなる? を1文で書く🙂
演習2:危険なPUTを“安全なPUT”に直そう⚠️➡️✨
次の仕様は危険かも?😵
- 「PUT するたびに
amountに +100 する」
✅ これを「置き換え」設計に直すなら、どういう body にする? (ヒント:最終状態を送る!)
演習3:DELETE のレスポンス設計を決めよう📨
-
2回目 DELETE のとき
- 204 にする? 404 にする?
- それぞれのメリットを1行で✨
AI活用🤖💞(“理解するため”に使うやつ!)
① メソッド選択クイズを作ってもらう🎮
「GET/PUT/DELETE のどれが自然か」を10問作らせると強いよ💪 例プロンプト👇
あなたはAPI設計の先生です。
GET/PUT/DELETEの使い分けクイズを10問作ってください。
各問に、1行の理由も付けてください。
対象は「注文API(注文作成/参照/更新/削除)」です。
② “危険な実装”チェック係にしてもらう👀⚠️
自分のPUT/DELETE案を貼って、 「冪等性を壊してる可能性ある?」って聞くのが超便利✨
このPUT/DELETE設計は冪等性を壊す可能性がありますか?
壊すなら、どの副作用が原因になり得るかを箇条書きで指摘して。
その上で、冪等に寄せる修正案を2つ出して。
まとめ🧁✨(この章のチェック✅)
- GET は基本「読むだけ」=冪等&Safe 🫶 (rfc-editor.org)
- PUT は「置き換え」=同じ入力なら同じ状態にしやすい🧱 (MDNウェブドキュメント)
- DELETE は「存在しない状態にする」=2回やっても最終状態が同じ🗑️ (rfc-editor.org)
- でも!メソッド名だけじゃなく 実装の副作用で冪等は簡単に壊れるよ⚠️ (rfc-editor.org)