11

データベースにアクセスする RESTful Web サービスを実装しています。データベース内のエンティティは、複数の更新を検出するためにバージョン管理されています。たとえば、現在の値が{"name":"Bill", "comment":"tinker", "version":3}の場合、1 人のユーザーが PUTを実行{"name":"Bill", "comment":"tailor", "version":3}すると、リクエストは成功し (200 OK)、新しい値は になります{"name":"Bill", "comment":"tailor", "version":4}。2 番目のユーザーが{"name":"Bill", "comment":"sailor", "version":3"}その要求を PUT すると、バージョン番号が一致しないため、失敗します (409 競合)。

既存の非 RESTful インターフェイスがあるため、データベースの設計を変更することはできません。RESTful インターフェイスは、バージョン チェックの詳細を処理する既存のインターフェイスを呼び出します。

RESTful Web サービスの経験則は、可能な限り HTTP の詳細に従うことです。この場合、リクエストで条件付きヘッダーを使用し、バージョンが一致しない場合は 412 Precondition Failed を返す方がよいでしょうか? 適切なヘッダーは If-Match のようです。このヘッダーは、リソースの現在の状態の表現のハッシュである可能性がある ETag (エンティティ タグ) を取ります。

私がこれを行った場合、ETag は外観のためのものになります。なぜなら、バージョンはまだ私がテストしている本物だからです。

「よりRESTfulにする」以外に、これを行う必要がある理由はありますか?

4

1 に答える 1

20

HTTP を使用している場合は、常に HTTP 仕様に従うことが適切です。その理由は、仕様を理解している人が正しく機能できるようにするためです。

412 は、前提条件(If-Match など) によってバージョンの照合が失敗した場合にのみ使用する必要がありますが、エンティティが競合を引き起こす場合は 409 を使用する必要があります (HTTP 仕様自体は、 409 の定義でこの動作を暗示しています)。

したがって、ETag を送信しないクライアントは 412 を予期しません。逆に、ETag を送信するクライアントは、409 の原因が ETag であることを理解できません。

私は1つの方法に固執します。「データベース スキーマは変更できない」とあなたは言いますが、(HTTP サーバー層で) データベース表現からバージョンを抽出し、それを ETag に入れ、途中で、 If-Match ヘッダーを取得して、バージョン フィールドに戻します。

ただし、エンティティ本体自体で完全に行うことは禁止されていません。概念とその仕組みを説明するだけで済みますが、ETag ソリューションでは、人々に HTTP 仕様を示すだけで済みます。

編集:バージョン フラグは、現在のリソースのハッシュである必要はありません。バージョンは非常に受け入れられます。 ETag: "3"は完全に有効な ETag です。

于 2010-09-02T15:19:23.627 に答える