コンピュータ サイエンスにおけるべき等性とは、オペレーションを複数回行っても、1 回だけ行った場合と同じ最終的な効果が得られるという特性です。同じリクエストをサーバーに 5 回送信した場合、べき等システムでは、最初の試行が問題なく完了した後、サーバー側のシステム状態が変わらないことを保証します。
べき等オペレーションの重要な特徴は、同じ結果が保証されることだけでなく、追加の呼び出しによって副作用が発生しないことです。これは、断続的なネットワーク障害やタイムアウトによってクライアントが同じメッセージを複数回送信する可能性がある、復元性のある分散システムを構築する際の必須要件です。
例: エレベーターの「上」ボタンを思い浮かべてみてください。1 回押すと、エレベーターが自分の階に呼び出されます。待っている間にさらに 10 回押しても、結果は同じで、エレベーターは 1 台しか来ません。ボタンを複数回押しても、エレベーターが 10 台来るわけではありません。一方、デジタル ショッピング カートにアイテムを追加する操作は、通常はべき等ではありません。[カートに追加] ボタンを 5 回クリックすると、その商品が 5 個カートに追加されることになります。
タイムアウトや接続の切断後にリクエストを安全に再試行し、アクションの重複(クレジット カードの二重請求など)を回避できます。
ユーザーは、以前のリクエストが成功したかどうかを知るために、複雑な状態トラッキングを行う必要はありません。単に「成功するまで再試行」すればよいのです。
分散システムは、ログを確認したり、見逃したメッセージを再送信したりすることで、データを破損させることなく障害から復旧できます。
REST 標準では、さまざまな種類のウェブ リクエストの動作が定義されています。HTTP メソッドの中には、設計上「安全」またはべき等であるものがあります。つまり、仕様上、繰り返されても予測可能な動作をすることが期待されています。一方、新しいデータを作成するように設計されているものもあり、その場合、再試行を安全に行うために、特別な注意が必要です。
RFC 9110 によると、いくつかの標準メソッドは本質的にべき等です。これらのアクションを繰り返しても、最初のリクエスト以降、サーバーの状態は変わりません。
一部のメソッドは、新しいデータを作成したり、既存のレコードの一部を変更したりする方法でデータを変更することが主な役割であるため、べき等ではありません。
構築するシステムでは、べき等性が求められることがよくあります。場合によっては、べき等性を自ら確保しなくてもよいことがありますが、そうでない場合は、デベロッパーが自ら対応し、べき等性を確保する必要があります。
最も有名な例は「二重請求」の問題です。ユーザーが航空券の支払いをしようとしているときにブラウザがフリーズした場合、ユーザーは [支払う] をもう一度クリックする可能性があります。べき等キーを使用する決済 API では、2 回目のクリックが再試行として認識されます。これにより、お客様の銀行口座が保護され、重複した取引の払い戻し処理にかかる運用コストが削減されます。
Terraform や Ansible などのツールはべき等性に依存しています。「10 GB のストレージ バケットを作成する」スクリプトを実行すると、ツールはクラウドの現在の状態を確認します。
最新のウェブ API では、デベロッパーがより堅牢な統合を構築できるように、Idempotency-Key ヘッダー(現在は IETF の標準化されたドラフト)が実装されていることがよくあります。
「upsert」(更新または挿入)は、従来のべき等データベース オペレーションです。単純な「挿入」ではなく、upsert は「このレコードが存在する場合は更新し、存在しない場合はレコードを作成する」というものです。
Google Cloud には、デベロッパーがこれらのパターンを簡単に実装できるツールがいくつか用意されています。マネージド プラットフォーム上に構築することで、データの安全性を確保するために記述する必要がある「ボイラープレート」コードの量を減らすことができます。