冪等性を一言でいうと
冪等性(べきとうせい)は、
「同じ操作を何回繰り返しても、最終的な結果が変わらない性質」
のことです。
1 回やっても、10 回やっても、「状態」が同じなら冪等。
回数によって結果が変わるなら非冪等。
HTTP メソッドや API 設計を考えるときに、めちゃくちゃ重要なキーワードです。
まずは直感イメージからつかむ
冪等な操作の例
玄関の電気のスイッチを「消す」ボタンだとします。
「消す」ボタンを 1 回押して電気が消えた。
2 回目押しても、3 回目押しても、電気は「消えたまま」。
このとき、
「電気を消す」という操作は、
何回やっても最終状態(消えている)が変わらないので、冪等です。
非冪等な操作の例
貯金箱に 100 円を入れる操作を考えます。
1 回入れたら +100 円。
2 回入れたら +200 円。
3 回入れたら +300 円。
回数によって結果(残高)が変わります。
これは冪等ではありません。
HTTP と冪等性の関係
HTTP メソッドごとの冪等性
HTTP の世界では、
メソッドごとに「冪等かどうか」が決まっています(設計上そうあるべき、とされている)。
GET:冪等
PUT:冪等
DELETE:冪等
POST:非冪等(が普通)
ここがとても大事です。
GET が冪等な理由
GET は「読むだけ」です。
同じ URL に対して GET を 1 回送っても、10 回送っても、
サーバー側の状態は変わりません。
だから冪等です。
PUT が冪等な理由
PUT は「このリソースを、この内容で上書きして」です。
PUT /users/1
{
"name": "Alice",
"age": 20
}
HTTPこの PUT を 1 回送っても、10 回送っても、
最終的にユーザー 1 の状態は「Alice, 20」のままです。
だから冪等です。
DELETE が冪等な理由
DELETE /users/1 を 1 回送ると、ユーザー 1 は削除されます。
2 回目以降送っても、すでにいないので「いない状態」のままです。
最終状態は「ユーザー 1 は存在しない」で変わらないので、冪等です。
POST が冪等ではない理由
POST /users で新規ユーザーを作る API を考えます。
同じ POST を 3 回送ると、
ユーザーが 3 人作られる可能性があります。
回数によって結果が変わるので、非冪等です。
なぜ冪等性がそんなに重要なのか
ネットワークは「同じリクエストを複数回送る」ことがある
現実のネットワークでは、
タイムアウトやエラーが起きたときに、
クライアントや中継サーバーが「同じリクエストを再送」することがあります。
もしそのリクエストが冪等なら、
何度送られても最終状態は変わらないので、安全です。
もし非冪等なら、
再送によって「意図しない重複作成・重複更新」が起きる危険があります。
だから、
「この操作は冪等であるべきか?」
「冪等でないなら、どうやって二重実行を防ぐか?」
を考えることが、堅牢な API 設計には欠かせません。
キャッシュや中継サーバーの最適化にも関わる
GET が冪等であることを前提に、
ブラウザや CDN は GET の結果をキャッシュしたり、
中継サーバーがリクエストをまとめたりできます。
もし GET が副作用を持っていたら、
こうした最適化は危険になってしまいます。
冪等性は、
「ネットワーク全体が安心して賢く振る舞えるための前提条件」
でもあります。
Java(Spring)で冪等性を意識する場面
更新系 API を設計するとき
例えば、ユーザー更新 API を考えます。
「この API を何回叩いても、最終状態は同じか?」
と自問してみてください。
PUT で「この状態にして」と送るなら、
同じ PUT を何回送っても結果は同じ → 冪等。
一方、
「ポイントを +10 する API」を PUT や PATCH で作ると、
同じリクエストを 3 回送ると +30 になってしまい、非冪等です。
そういう「加算系」「インクリメント系」は、
冪等ではないことを理解したうえで、
二重送信対策(トークン、リクエスト ID など)を考える必要があります。
サービス層の設計で「最終状態」を意識する
冪等な API を作りたいときは、
「変化量」ではなく「最終状態」を指定する設計に寄せるとよいです。
変化量:「ポイントを +10 して」 → 回数で結果が変わる
最終状態:「ポイントを 100 にして」 → 何回やっても 100
サービス層のメソッドも、
addPoint(userId, 10) よりsetPoint(userId, 100)
の方が冪等にしやすい、という感覚を持っておくと、
設計の選択肢が変わってきます。
初心者向けまとめ:冪等性を自分の言葉で説明するなら
あなたの言葉で整理すると、こうなります。
冪等性とは、
「同じ操作を何回繰り返しても、最終的な状態が変わらない性質」のこと。
HTTP では、
GET・PUT・DELETE は冪等、
POST は普通は冪等ではない。
ネットワークの再送やキャッシュを安全に行うために、
どの API を冪等にするか、
どの API は非冪等として扱うか、
を意識して設計することが大事。
もしよければ、
今あなたがイメージしている API を一つ挙げて、
「これは冪等か? 同じリクエストを 3 回送ったらどうなるか?」
を一緒に言語化してみよう。
その問いを自分で回せるようになると、設計の“怖さ”がかなり減っていくから。
