web-dev-qa-db-ja.com

PATCHが安全でもべき等でもないのはなぜですか?

PUTがある場所でPATCHが安全でない理由を理解できません。べき等の部分-リソースのフィールドを更新すると、そのフィールドは更新後に同じ値を返さないのですか?

17
Tony Vincent

まず、PUTも安全ではありません。

安全なメソッドは、リソースを変更しないHTTPメソッドです。たとえば、リソースURLでGETまたはHEADを使用する場合は、リソースを変更しないでください。

PUTリクエスト(したがって、PATCHも同様)はリソースを更新するため、リソースをキャッシュできず、安全ではありません。

PUTリクエストはべき等ですが、PUTリクエストはべき等である必要があります。

べき等HTTPメソッドは、さまざまな結果なしに何度も呼び出すことができるHTTPメソッドです。メソッドが1回だけ呼び出されても、10回以上呼び出されても問題ありません。結果は同じになるはずです。繰り返しますが、これは結果にのみ適用され、リソース自体には適用されません。この情報は、(現在の)リソース表現で共有されていない限り、(update-timestampのように)操作できます。

PUTリクエストがべき等であることの背後にある考え方は、リソースの更新呼び出しが失敗した場合、クライアントが望ましくないまたは一貫性のない状態を引き起こさずに同じ呼び出しを再度行うことができるということです。 PUTリクエストの前には常にリソースへのGETリクエストが必要であり、リソースのみが変更されていない場合は成功します。詳細について:-同様の答えのいずれかを実行します- 同時実行環境でのべき等PUT要求

現在、PATCHリクエストは選択フィールドのみを更新することを目的としており、リソース表現を取得することは想定されていません。そのため、PATCHリクエストを複数回呼び出すと、リソースの状態に望ましくない変化が生じる可能性があります。したがって、IDEMPOTENTではありません。

例:-リソースPersonがあります

リクエスト1:PATCH/person/1 {'age':10}-リソースの年齢を10に更新します

次に、他の並列リクエストがリソースの状態を変更するとします。

リクエスト2:PATCH/person/1 {'age':19}-リソースの年齢を19に更新します

リクエスト1を再度送信すると、リソースの有効期間が再度10に更新されるため、望ましくない結果が発生します。

EtagsまたはIf Modified sinceヘッダーを使用して、べき等にすることができます。

1
hspandher

これはsafeではありません。一般に、リソースを変更せずにPATCHリクエストを安全に実行することはできないためです(そのためです)。

それで、なぜPATCHはPUTと比較してべき等ではないのですか?変更を適用する方法が重要だからです。リソースのnameプロパティを変更する場合は、{"name": "foo"}などをペイロードとして送信します。このリクエストを何度も実行すると同じ結果になるため、実際にはべき等です。結果:リソースのname属性が「foo」になりました。

しかし、PATCHは、リソースを変更する方法がはるかに一般的です(JSONパッチを適用する方法について this 定義を確認してください)。また、たとえば、リソースを移動することを意味し、{ "op": "move", "from": "/a/b/c", "path": "/a/b/d" }のようになります。 2回目の呼び出しでエラーが発生するため、この操作は明らかにべき等ではありません。

したがって、ほとんどのPATCH操作はべき等である可能性がありますが、そうでないものもあります。

他の答えに対する1つの注釈:べき等は、操作を続けて複数回繰り返すことによって定義されます。他の操作がその間または並列で実行された場合は効果が異なるため、べき等ではないと言うことは有効な引数ではありません(その場合、操作は通常べき等ではありません)。数学的には、べき等変換は、どれほど頻繁に適用したとしても(360度回転させるなど)、同じ結果をもたらす変換です。もちろん、間に360度の回転が2つある場合、他の操作を適用すると結果が異なる可能性があります。

18
C. Doe

PATCHはリソース属性を変更します。変更には、属性の以前の具体的な値が必要な場合があり、そのため、べき等ではありません。

From Name=John to Name=Gargantua. 

繰り返し適用すると、名前はGargantuaになり、パッチは失敗します。変更前に名前を「John」にする必要があるためです。

"from Name=John"

5
Skip

最近、Patchがべき等であるかどうかを調べ始め、JSONパッチ形式について読んだ後、Patchメソッドを使用して追加操作を適用した場合、新しい値を同じリクエストが複数回行われた場合、既存のリソース。

{"op": "add"、 "path": "/ a/b/c"、 "value":["foo"、 "bar"]}

4
user1570094