15

私は最近、HTTP 1.1仕様を読み、それをRESTに関連付けることに多くの時間を費やしました。HTTP DELETEメソッドには、その「べき等性」と安全性に関して2つの解釈があることがわかりました。これが2つのキャンプです:

  1. HTTP DELETEを使用してリソースを削除し、それが成功した場合(200 OK)、そのリソースをN回削除しようとすると、それらの削除呼び出しごとに成功メッセージ(200 OK)が返されます。 。これがその「無力さ」です。

  2. HTTP DELETEを使用してリソースを削除し、成功した場合(200 OK)、そのリソースを再度削除しようとすると、リソースが削除されたため、エラーメッセージ(410 Gone)が返されます。

仕様では、DELETEはべき等であると述べていますが、べき等イベントのシーケンスは依然として副作用を引き起こす可能性があるとも述べています。私は本当に2番目のキャンプが正しいと感じています、そして最初のキャンプは誤解を招きます。以前に削除されたリソースを削除する原因であるとクライアントに考えさせることで、どのような「安全性」を導入しましたか?

最初のキャンプにはたくさんの人がいて、そのテーマについて何人かの著者がいるので、人々を最初のキャンプに導く感情以外の説得力のある理由があるかどうかを確認したいと思いました。

4

3 に答える 3

21

べき等であるということは、リクエストに副作用が許可されていないことを意味するわけではありません(これが「safe」プロパティの説明です)。同じリクエストを複数回発行しても、異なる副作用や追加の副作用が発生しないことを意味します。

私の意見では、後続のDELETE要求はエラーを返すはずです。サーバーの状態は、DELETE要求が1つだけ行われた場合と同じであるため、べき等です。次に、200OKステータスを返すこともOKになるはずです-べき等であるために後続のDELETE要求のエラーコードを返す必要はないと思います-エラーステータスを返す方が私には理にかなっているようです。

于 2009-04-12T02:51:13.917 に答える
2

@MichaelBurrは、べき等性と副作用について正しいです。

私の意見では、特定のRESTリクエストには、クライアントの状態とサーバーの状態の2つの状態が関係しています。RESTは、サーバーとクライアント間でこれらの状態を転送することを目的としています。これにより、クライアントの状態がサーバーの状態のサブセットにマップされます。つまり、サブセットはサーバーとの整合性が保たれます。そのべき等性のために、後続のべき等要求は、要求を1回だけ行う場合とはどちらの状態も異なる結果にならないことを意味する必要があります。最初のDELETEでは、サーバーがリソースを削除し、クライアントにもリソースを削除できることを通知します(リソースは「もう存在しない」ため)。これで、両方の状態が以前と同じになり、削除されたアイテムが差し引かれます。クライアントがアイテムを削除しようとしたときに別のことを行うには、サーバーからクライアントに転送される状態に別の情報が含まれている必要があります。サーバーは、リソースがすでに削除されているという情報を使用して少し異なる方法で処理を実行できますが、何か別の応答を行うと、メソッドのべき等性は本質的に壊れます。

べき等関数の場合:

delete(client_state) -> client_state - {item}
delete(delete(client_state)) -> client_state - {item}
delete(client_state) = delete(delete(client_state))

このべき等性を保証する最良の方法は、サーバーの応答が同一である場合です。つまり、クライアントの状態がべき等性を破る唯一の方法は、クライアントの応答の処理に不確定性または副作用があることです(これはおそらくポイントです)応答を処理する誤った実装に)。

転送中の状態(REST)の表現の外にステータスコードが存在するというクライアントとサーバー間の合意がある場合、アイテムが「もう存在しない」ことをクライアントに通知することができます(そうなるように)最初のリクエストで)以前に削除されたという追加のコメントがあります。クライアントがこの情報をどのように処理するかは不明ですが、結果のクライアントの状態に影響を与えることはありません。ただし、ステータスコードを使用して状態を伝達することはできません。または、他の状況(「このアイテムを削除する権限がない」や「アイテムが削除されなかった」など)でも状態を伝達する場合は、いくつかの導入されたあいまいさや混乱があります。それで、それでも、サーバーの応答は、同一の以前のDELETE要求に依存します。

HTTPリクエストにはremoveメソッドが含まれるため、関数は次のようになります。

delete(client_state) = send_delete(client_state) -> receive_delete(client_state) 
                                                 -> respond_to_delete(informative_state) 
                                                 -> handle_response(informative_state) 
                                                 -> client_state - {item} 
于 2012-10-22T18:58:01.500 に答える