用語集 · API テスト
冪等性(べきとうせい)
英語: Idempotency
別名: べき等性, 冪等, べき等, idempotent
定義
同じリクエストを 1 回送っても何回送ってもサーバーの状態が同じになる性質です。GET、PUT、DELETE は冪等ですが、POST は冪等ではありません。
操作が冪等であるとは、それを繰り返してもサーバーへの影響が 1 回だけ行った場合と同じになることです。これが重要なのは、ネットワークは失敗するものだからです。タイムアウトしたクライアントにはリクエストが届いたかどうかが分からず、リトライが安全なのはリクエストが冪等な場合だけです。冪等性はサーバーの状態に関する性質であり、毎回同一のレスポンスが返ることではありません。
冪等な HTTP メソッド
| メソッド | 冪等 | 安全(副作用なし) |
|---|---|---|
GET、HEAD、OPTIONS |
はい | はい |
PUT |
はい | いいえ |
DELETE |
はい | いいえ |
POST |
いいえ | いいえ |
PATCH |
保証されない | いいえ |
DELETE /orders/42 を 2 回送ると、204 の次に 404 が返るかもしれません。レスポンスは異なりますが、状態は同じで、注文は削除されています。これはやはり冪等です。
PUT と PATCH の違い
PUT はリソース全体を送信したボディで置き換えます。{"name": "Ada", "plan": "pro"} を付けて PUT /users/7 を 3 回送っても毎回同じユーザーが残るので、冪等です。
PATCH は変更を適用するもので、冪等かどうかは変更の内容によります。{"plan": "pro"} は値を設定するので、実際には冪等です。「loginCount を 1 増やす」といった操作や、配列への JSON Patch の add は毎回異なる結果になるため、メソッドとしての PATCH は冪等であることが保証されません。
POST を安全にリトライできるようにする
決済や注文の API は、冪等キー(Idempotency Key)を受け付けることがよくあります。クライアントが一意の値を生成し、Idempotency-Key のようなヘッダーで送信します。サーバーはそのキーでの最初のリクエストの結果を保存し、繰り返しのリクエストには 2 件目の注文を作る代わりに同じ結果を返します。
POST /payments HTTP/1.1
Content-Type: application/json
Idempotency-Key: 6f1c2a9e-3b7d-4f0a-9c2e-1d5b8a7e4f60
{"amount": 4999, "currency": "EUR"}
テスト方法
- 同じ
PUTやDELETEを 2 回送り、ステータスコードだけでなくリソースの状態をアサートします。 - 同じ冪等キーで同じ
POSTを 2 回送ります。リソースが 1 つだけ作られ、レスポンスボディが同じであることを期待します。 - 異なるボディでキーを再利用します。よく設計された API は、古い結果を黙って返すのではなく、これを拒否します。
- 重複したリクエストを同時に送ります。冪等性の処理が壊れやすいのは競合状態(レースコンディション)です。