REST(あるいは、少なくともHTTP)の重要な側面の一つはいくつかの操作(動詞)がべき等である、という概念である。Gregor Roth氏は数年前に次のように言っている:
PUTメソッドはべき等である。メソッドがべき等であるとは成功したリクエストの結果はそれが実行された回数と無関係である、という意味である。
また、べき等はSOAデザインパターンにおいても議論されている。ここ数年、RESTとREST以外の手法にはないメリットについて多くのことが語られてきたが、べき等についてはまだまだ理解が足りず、完全には精査されていない1つの側面として取り残されてきた。しかし、SOAメーリングリストの最近の投稿から、多くの人が仮定しているようにみえる考えについてのかなりストレートな多くの議論が巻き起こっている。最初の投稿はこのように始まっている:
現在、私は私たちのサービスのべき等性に着目し、企業がべき等なサービスをつくる場合に使える手引き書を提供しようとしています。質問は、全てのサービスはべき等でなければならないかどうか、ということです。それは現実的なことでしょうか?
その投稿は別のブログエントリを引用しているが、そこでは筆者が次のような主張をしている:
もちろん、べき等性を実装することはサービスプロバイダにとって複雑なこともあるでしょう。そして、複雑さはコストにつながります。おそらく、このことがべき等なサービスがほとんどないということの真の理由です。[...] しかし、一度サービスをべき等にしてしまえば、それは誰にでも扱えるものになり、実装の境界をまたぐデータの一貫性を保証することができます。サービスはべき等につくられるべきなのです。それはアーキテクチャとサービス設計における原理であるべきです。多くのサービス利用者によって使われるサービスに対しては特にそうです。データの一貫性を保つ複雑さは、サービス実装者であるあなた自身が対処すべきであって、それをサービス利用者に押しつけることはできませんよね? 利用者はあなたの顧客であり、顧客として扱うべきでしょう。利用者が使いやすくなれば、あなたはより多くの顧客を得ます。
この最初の投稿は多くの反応を生んだ。その中にCap GeminiのSteve Jones氏からのものがあり、そこで次のように言っている:
べき等性はITにおけるあまりにくだらないフレーズの一つであり、その意味するところは'メモリ内でのべき等性'ということだ。もしあなたが更新機能を有するコメントサービスを持っているとする。呼び出し側から見ればそのサービスは状態を維持し管理しなければいけない。あなたが意図すべきは、メモリ内で水平にスケールすることができるかどうかだ。データベースの中も含めて状態を更新するなら、べき等にはなり得ない。べき等性は、ここでは同じ関数を同じ値で呼び出したときに結果が同じであるということだが、これは数学的定義なのだ。もし状態を更新してしまったら、べき等ではないし、その'データベースの更新'は何も変更できなくなる。
過去にRESTに関して多くの投稿をしてきたMark Baker氏はSteve氏に次のように応えた:
あなたのコメントサービスの例のように、べき等でない状態の更新はあるが、あるデータをある特定の値に設定するようなべき等な更新も存在する... これは明らかに、同じ入力で何度実行しても、結果が同じになるからだ。
ある操作が同じ入力値に対して何も変更しないのであれば、それは数学的にべき等である、という点についてはSteve氏はMark氏に同意している。しかしながら、その操作によって何らかの状態の更新が引き起こされるのであれば、例えばそのリクエストが行われた最新時刻を記録するような場合においては、それはべき等ではない。
私は、IT業界において今日この言葉がどのように誤用されているかについてとても'感銘を受けて'います。これまで私は、何かが'べき等'であると語られるその理由が、その利用者の影響でトランザクションが記録されるとしても、メモリ内ではステートフルでない、ということであるような状況を何度か見てきました。
Mark氏はSteve氏の厳密な定義に同意しているが、それがもとの質問にあるようなリクエストの文脈においては適用されない、と信じている。つまり、分散システムにおけるべき等性である:
[...] この言葉は実装ではなくインターフェースについて語るときにのみ意味がある言葉だ。だから、仮に私が操作、例えば"set"を定義して、べき等であるようにするなら、それはクライアントに関することだけが重要であって、そのインターフェースの実装の一部としてログエントリーが生成されようとも関係がないのだ。
もう一人の回答者、Ashaf Galal氏はすべての"読み取りサービス"はべき等である、と主張している。それはそのサービスが単にデータを返すだけだからだ。しかしながら、Steveが指摘しているように、この見方はあまりにも単純であり、操作がべき等に見えるかもしれないが、その実装はべき等どころではないかもしれない(そして、ここで再度この区別が重要かどうかについての疑問が持ち上がる):
[...] 読み取り機能はべき等である必要はない。'getNextIterator()'は読み取り機能だがそのイテレータがインクリメントされるのだからべき等ではない。銀行口座へのリクエストは、それによって監査ログが作られるので、べき等ではないと言えるだろう。(その間に変更が起きない)2つの連続した呼び出しに対して返された結果が同じであるかもしれないが、ログエントリは異なるはずだ。
Ashaf氏はSteve氏に、べき等性はサービスの特性であってインターフェースの特性ではない、と反論した。
クライアントは、そのサービスから適切なレスポンスを得る必要があるのであって、サービスがべき等かどうか、ログをとるかどうかを気にしない。
さて、皆さんはどう考えるだろうか? まだべき等性が意味するところに対する誤解があるだろうか? べき等だと考えられている操作が、実際にはSteve氏がいうようなログの更新などのある種の状態に対して変更を加えるかどうかは、重要なことと考えるだろうか?