サイド影響のあるPUTを使用しています(REST)


9

ユーザーがフォームを更新するたびに元に戻す履歴を作成したい。更新なので、PUTリクエストを使用したいと思います。ただし、PUTには副作用が必要ないことを読みました。

ここでPUTを使用することは許容されますか?より良い代替案はありますか?

PUT /person/F02E395A235

{
   time: 1234567,
   fields: {
      name: 'John',
      age: '41'
   }
}

サーバー内

doPut('person/:personId',
   // create a new person snapshot
)

編集:

履歴はユーザーに表示され、複数回呼び出すと複数のバージョンになります。

解決策は、バージョンを作成する前にバージョンが一意であるかどうかを確認することでした。

回答:


10

HTTP / 2を起草している人々は、古い意味を保持しながら、HTTPが何をすべきかについての彼らの考えについてはるかに冗長でした。べき等についてHTTP / 2ドラフト仕様が何を述べているか見てみましょう:

4.2.2。べき等メソッド

リクエストメソッドは、そのメソッドとの複数の同一リクエストのサーバーへの意図した影響が単一のそのようなリクエストの影響と同じである場合、「べき等」と見なされます。この仕様で定義されているリクエストメソッドのうち、PUT、DELETE、および安全なリクエストメソッドはべき等です。

安全の定義と同様に、べき等プロパティはユーザーが要求したものにのみ適用されます。サーバーは、各要求を個別にログに記録したり、リビジョン管理履歴を保持したり、べき等の要求ごとに他の非べき等の副作用を実装したりできます

このような各PUT要求がサーバーに及ぼす影響は、そのURIで識別されるリソース更新することです。これはまさにあなたの場合に起こることです。

ここでリソースのバージョンを決定することは重要ではありません。何も変更されていないときに新しいバージョンを作成したくない場合は、PUTリクエストのペイロードをリソースの最新の(または別の方法で識別された)バージョンと比較し、どのプロパティも変更されていない場合新しいバージョンを作成ないことを選択できます。


あなたの編集:

履歴はユーザーに表示され、複数回呼び出すと複数のバージョンが発生します

リソースに関する限り、それは副作用ではありません。そのURIのリソースは変更されません(同じプロパティがPUTを取得します)。履歴は、おそらく別のURIまたは別の要求ヘッダーで要求されるため、単なるメタデータです。


あなたが私の特定の問題に答える場合を除いて:「PUTがユーザーに表示可能な履歴を作成することは許容できますか?」そして解決策を私に与えてください
roo2

その解決策はどのような問題ですか?そのtimeプロパティが更新されますか?それはリソースにありますがそれもメタデータだと思います。
CodeCaster

1
問題は、複数のPUTが送信された場合、ユーザーが冗長な情報を含む長い取り消し履歴を取得することでした。一意性をチェックすることで解決します
roo2 2013

12

HTTPは2つのプロパティを区別します。

  • べき等
  • 安全性

べき等は、仕様によって次のように定義されます。

メソッドは、「べき等」のプロパティを持つこともできます(エラーまたは期限切れの問題は別として)N> 0の同一リクエストの副作用は単一リクエストの場合と同じです。方法はGETHEADPUTおよびDELETEこのプロパティを共有しています。また、メソッドOPTIONSと副作用があるTRACE べきではないので、本質的にべき等です。

そして安全性:

特に、GETHEADメソッドには、取得以外のアクションを実行することの重要性がないという規約が確立されています。これらの方法は「安全」であると考えられるべきです。これは、ユーザエージェントのような他の方法を、表現することができPOSTPUTそしてDELETEユーザは、おそらく危険なアクションが要求されているという事実を認識させられるように、特別な方法で、。

当然、GETリクエストを実行した結果としてサーバーが副作用を生成しないようにすることはできません。実際、一部の動的リソースはその機能を考慮しています。ここでの重要な違いは、ユーザーが副作用を要求しなかったため、それらに対して責任を負うことができないことです。

安全性はべき等を意味することに注意してください。メソッドに副作用がない場合、メソッドを複数回実行すると、それを1回実行した場合と同じ副作用、つまりなしになります。

これにより、メソッドは3つのカテゴリに分類されます。

  • 安全な(これもとべき等): 、GET、、HEADOPTIONTRACE
  • べき等であるが必ずしも安全ではない:PUTDELETE
  • べき等でも安全でもない: POST

PUTは副作用がない必要があります。

それは間違いです。PUTべき等ですが安全ではありません。の要点PUT、副作用、つまりリソー​​スの更新を行うことです。べき等性とは、同じリソースを同じ内容で複数回更新すると、1回だけ更新するのと同じ効果が得られるということです。

安全性に関するセクションの最後の段落に注意してください(強調は私のものです):

当然、GETリクエストを実行した結果としてサーバーが副作用を生成しないようにすることはできません。実際、一部の動的リソースはその機能を考慮しています。ここでの重要な違いは、ユーザーが副作用を要求しなかったため、それらに対して責任を負うことができないことです。

この文はGET安全性について述べていますが、著者も同じ推論とべきPUT等性を適用するつもりであったと考えられます。IOW:ユーザーに見える副作用、つまり名前付きリソースの更新がPUT1つだけあるはずです。それはあり、他の副作用を持っていますが、ユーザーは、彼らのために責任を負うことはできません。

たとえば、べき等であることは、何度でもPUT再試行できることを意味します。仕様では、複数回実行すると1回実行する場合とまったく同じになることが保証されています。これらの複数のPUTリクエストの副作用として、古いリビジョンのバックログを作成することは完全に有効です。ただし、複数回の再試行の結果、データベースが古いリビジョンのバックログで一杯になった場合、それは私の問題ではありません。

IOW:副作用はいくつでも許されますが、

  1. ユーザーの要求がべき等であるかのようにユーザーに見える必要があります
  2. ユーザーではなく、これらの副作用に責任があります

うん、べき等は、置かれているリソースの状態に関するものであり、PUTの動作によって影響を受ける他のサーバー/サービスの状態に関するものではありません。
Marjan Venema 2013

Restの安全性と
べき

素晴らしい説明。ただし、次のようなステートメントをいくつか作成します。「PUTの目的は、副作用、つまりリソー​​スを更新することです」これは、「副作用」という用語で「主な意図された効果に加えて発生する副次的または意図的でないもの」とは異なるものを意味しない限り、矛盾しているように見えます。
MarredCheese

@MarredCheese:私は標準的なプログラミングの意味でこの用語を使用しています。これは基本的に「戻り値ではない「結果」」を意味します。
イェルクWミッターク

ああ、もちろん。説明をありがとう。
MarredCheese

1

PUTに副作用が必要ないことは正しいですが、これに何かを追加します。

PUTは、そのPUT操作が実行されているリソースに影響を与える必要がない

personとして識別されているリソースを更新しているF02E395A235ため、PUTを使用するのが適切です。ここで、ビジネスルールとして、呼び出し元のエンティティ(RESTサービスのコンシューマー)からは見えない変更も追跡します。これは、personリソースに新しいアイテムを追加しません。/person/エンドポイントを使用して履歴スナップショットにアクセスすることはできません。したがって、この場合、PUTは完全に許容できるはずです。


1
配置されるリソースへの副作用はありませんが、他のもの(カウンター、ロギング、監査トレースなど)への副作用はいくつでも許容できます。
Marjan Venema 2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.