6

次のように、会社の名前を変更する API を実装しました。

PUT /companies/A
{
  "name": "B"
}

会社の新しい URI: を指すヘッダーで返さHTTP 301れます。Location/companies/B

If-Matchヘッダーの有無にかかわらず、この操作を冪等にするにはどうすればよいですか?

  1. ヘッダーなしIf-Match: ユーザーが存在しない会社の名前を変更しようとすると、サーバーが返されることを期待しますがHTTP 404、正当な名前変更操作はべき等ではないため、そうすることができません (最初に返さ301れ、最初に返され、404後続の呼び出しで)。失敗した名前変更 (会社が存在しない) と既に行われた名前変更をクライアントが区別できるようにしたいので、これは問題です。

  2. If-Matchヘッダーあり: 会社が会社名に依存している場合、ETag前提条件が成り立たなくなるため、その後の名前変更操作は失敗します。繰り返しますが、これにより、実際には既に実行されている操作が失敗したように見えます。

4

3 に答える 3

7

OK、これは 2 年前のものですが、他の誰かが私と同じようにつまずいた場合に備えて、回答します。

簡単に言えば、HTTP の観点からは、リソースの名前変更 (移動) は冪等ではなくPOST、代わりにPUT.

長い答え: RFC 2616PUTで次のように定義されている「作成または置換」操作です(私の強調):

このメソッドは、囲まれたエンティティが指定された Request-URI の下PUTに格納されることを要求します。

RFC 7231 (この質問がされた時点では草案としてのみ存在していました) は、より明確に次のように述べています。

このPUTメソッドは、ターゲット リソースの状態を作成するか、要求メッセージ ペイロードに含まれる表現によって定義された状態に置き換えることを要求します。与えられた表現が成功すると、同じターゲット リソースでの後続の結果として、同等の表現が( ) 応答で送信されるPUTことが示唆されます。GET200OK

名前の変更が成功すると、別の場所でリソースが使用可能になるため、PUTは適用されません。

PS。おそらくPUT、名前やその他の属性に関係なく、会社のある種の一意の識別子を要求本文に含めることで、これを機能させることができたでしょう。これにより、以前の名前変更を検出し、適切なリダイレクトを発行できます。それにもかかわらず、それはプロトコルに反していると思いますし、POSTもっと適切だったでしょう.

于 2015-10-19T09:00:05.607 に答える
2

PUT 操作は成功し、200 または 201 を返す必要があります。同じリソースに対する後続の要求は、新しいリソースの URI を示す適切な応答本文と共に 301 を返す必要があります。

404 は、本当に見つからないリソース、つまり、存在せず、存在しない企業に対してのみ使用する必要があります。

protocolで述べたように、冪等性とは、呼び出しが常に同じものを返すことを意味するわけではありません。副作用がないということです。また、冪等性は、2xx (301 など) 以外のエラー状態では適用されません。

私は本当に仕様でそれを正しくするというコミットメントを賞賛しますが、すべてのものと同様に、それは解釈の対象です.

于 2013-10-15T18:15:04.780 に答える