PATCHメソッドがべき等でないのはなぜですか?


48

私はこれについて疑問に思っていました。

フィールドとフィールドを持つuserリソースがあるidとしnameます。フィールドを更新したい場合は、次のようにリソースに対してPATCHリクエストを行うことができます。

PATCH /users/42
{"name": "john doe"} 

そして、アプリケーションはユーザー42の名前を更新します。

しかし、なぜこのリクエストを繰り返した場合、結果が異なるのでしょうか?

よると、RFC 5789

PATCHは安全でもi等でもありません


呼び出しの間に他の誰かがユーザー42の更新要求を行うとどうなりますか{"name": "bendjamin franklin"}
gnat 14年

@gnatは、代わりにべき等と見なされるPUTメソッドにも同様の引数を保持しませんか?(goo.gl/t24ZSJを参照)
mattecapu 14年

「PUTはべき等のセマンティクスを持っているため、絶対更新(つまり、リソースの状態全体をサーバーに送信)に安全に使用できますが、相対更新(つまり、リソース状態に変更のみを送信)には違反します。そのセマンティクス...」(POSTおよびPUTリクエスト-それは単なる慣習ですか?
gnat 14年

1
明らかに...しかし、2つの等しい要求の間で2番目のクライアントが2つの中間で3番目の要求を行うことができるため、PUTはべき等ではないと言うことができます。PATCH要求にも同じ引数が当てはまります。
マットカプ14年

2
私は、関連する仕様への参照を追加する自由を取りました。これは、この質問の文脈において非常に関連性があると思うからです。
ピート14年

回答:


34

PATCH要求 i 等である可能性がありますが、そうである必要はありません。それが、それが非べき等性として特徴付けられる理由です。

PATCHがべき等であるかどうかは、必要な変更がどのように伝えられるかに強く依存します。
たとえば、パッチ形式がの形式である場合、{change: 'Name' from: 'benjamin franklin' to: 'john doe'}最初の要求の後のPATCH要求は、最初の要求とは異なる効果(失敗応答)を持ちます。
非べき等性のもう1つの理由は、元のリソース以外のものに変更を適用すると、リソースが無効になる可能性があることです。これは、変更を複数回適用する場合にも当てはまります。


3
最後の段落はわかりませんが、「元のリソース以外のリソースに変更を適用するとリソースが無効になる可能性があります」という例を挙げてください。
ロビングリーン

3
@RobinGreen:リソースはXMLで表現され、最大で1つの<name>要素が必要であると仮定します。PATCHが<name>元々含まれていなかったリソースに要素を追加する場合、PATCHを2回適用する(または既にを含むリソースに適用する<name>)と、<name>許可されない2つの要素が突然含まれるため、リソースが無効になりますそのようなリソースのために。
バートヴァンインゲンシェナウ

13
最初に示した例は、dem等であるため、関連するIMHOではありません。べき等であるDELETEの例、最初の要求:リソースは存在したが削除された(2xxを返す)、2番目の要求:リソースは存在せず、要求の後も存在せず、4xxを返します。サーバーの状態は変わらないため、べき等性は変わりません。あなたの例では、最初の要求:BenFraからJohDoeへのPATCH、リソース名はBenFraでしたが、現在はJohDoe(2xxを返します)、2番目の要求:BenFraからJohDoeへのPATCH、リソース名はJohDoeであり、依然としてJohDoe(戻り4xx)です。したがって、これはPATCHが非べき等であることを示していません。
sp00m


8

dem等でないPATCHがRFC 5789からのこの段落であるとき、私は明確な答えだと思います:

既知のベースポイントからパッチ形式を操作する必要がない場合もあります(たとえば、ログファイルへのテキスト行の追加、またはデータベーステーブルへの非衝突行)。この場合、クライアントリクエストで同じ注意は必要ありません。 。

RFCではパッチにリソースへの「一般的な変更」が含まれていると規定されているため、単なる典型的なフィールドの置き換えに留まるべきではありません。リソースがカウンター用である場合、パッチはその増分を要求できますが、これは明らかにべき等ではありません。


2

PATCH要求はリソースに適用される操作のセットを記述します。同じリソースに同じ操作のセットを2回適用する場合、結果は同じではない場合があります。これは、操作を定義するのはあなた次第だからです。つまり、マージルールを定義する必要があります

PATCHJSONだけでなく、さまざまな形式のリソースにパッチを適用するためにリクエストを使用できることを忘れないでください。

したがって、マージルールをべき等になるように定義するとPATCHリクエストはべき等になる可能性があります。

べき等の例:

// Original resource
{
  name: 'Tito',
  age: 32
}

// PATCH request
{
  age: 33
}

// New resource
{
  name: 'Tito',
  age: 33
}

非べき等の例:

// Original resource
{
  name: 'Tito',
  age: 32
}

// PATCH request
{
  $increment: 'age'
}

// New resource
{
  name: 'Tito',
  age: 33
}

2番目の例では、属性をインクリメントするために作成した「Mongo like」構文を使用しました。同じリクエストを複数回送信すると毎回異なる結果になるため、明らかにこれはdem等ではありません。

今、あなたはそのような構成された構文の使用が有効かどうか疑問に思うかもしれません。規格によると、次のとおりです。

PUT要求とPATCH要求の違いは、サーバーが囲まれたエンティティを処理してRequest-URIで識別されるリソースを変更する方法に反映されます。PUTリクエストでは、同封されたエンティティは、オリジンサーバに保存されたリソースの修正バージョンと見なされ、クライアントは保存されたバージョンの置き換えを要求しています。ただし、PATCHの場合、囲まれたエンティティには、オリジンサーバーに現在存在するリソースを新しいバージョンを生成するためにどのように変更する必要があるかを説明する一連の命令が含まれています。

また、この方法でリクエストを使用するのは安らかなのかと疑問に思うかもしれませんがPATCH、多くの人はそうではないと考えています。この問題に関する多くのコメントを含む良い答えがあります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.