8

API に「変更された値を取得」機能を実装したいと考えています。たとえば、次の REST API 呼び出しがあるとします。

GET /ws/school/7/student

これにより、学校 #7 のすべての生徒が取得されます。残念ながら、これは多いかもしれません。そのため、特定の時間以降に変更された学生の記録のみを返すように API を変更したいと考えています。(ユースケースは、夜間のプロセスが別のシステムから実行され、すべての学生を私のシステムから彼らのシステムにプルすることです。)

http://blog.mugunthkumar.com/articles/restful-api-server-doing-it-the-right-way-part-2/では、if-modified-since ヘッダーを使用して次のような表現を返すことを推奨しています。

  • if-modified-since ヘッダーで要求された時間以降に更新されたすべての学生を検索します
  • 生徒がいる場合は、200 OK でそれらの生徒を返します
  • そのクエリから返された生徒がいない場合は、304 Not Modified を返します。

彼のやりたいことは理解できるが、これは間違ったやり方のようだ。If-Modified-Since ヘッダーの定義 ( http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.24 ) は次のように述べています。

If-Modified-Since リクエスト ヘッダー フィールドは、条件付きにするメソッドで使用されます。リクエストされたバリアントがこのフィールドで指定された時間以降に変更されていない場合、エンティティはサーバーから返されません。代わりに、メッセージ本文なしで 304 (変更されていない) 応答が返されます。

これは私には間違っているようです。RFC で示されているような表現や 304 を返すのではなく、いくつかのハイブリッドを返します。クライアント側のコード (またはさらに悪いことに、サーバーとクライアント間の Web キャッシュ) が意味を誤って解釈し、ローカルにキャッシュされた値を置き換えてしまう可能性があるようです。

だから、2つの質問:

  • これはヘッダーの正しい使用法ですか?
  • そうでない場合 (そして私はそうではないと思う)、ベストプラクティスは何ですか? クエリ文字列パラメータ?
4

1 に答える 1

7

これはヘッダーの正しい使い方ではありません。ヘッダーは、If-Modified-SinceHTTP クライアント (ブラウザーまたはコード) がリソースを要求するときにオプションでサーバーに提供できるものです。提供された場合、意味は「リソース X が必要ですが、時刻 T 以降に変更された場合のみ」です。その目的は、クライアント側でリソースをキャッシュできるようにすることです。

提案された使用法のセマンティクスは、「時間 T 以降に発生したコレクション X の更新が必要です」です。X のサブセットのリクエストです。キャッシュを有効にすることが動機のようには見えません。クライアント側のキャッシュされた表現には、X のすべてが含まれているように見えますが、通常の要求では X への小さな変更セットしか返されません。つまり、応答は直接キャッシュするものではないため、キャッシュはカスタム ユーザー ロジックのクライアント側で行う必要があります。

クエリ文字列パラメーターは、より適切なソリューションです。以下{seq}は、シーケンス番号またはタイムスタンプのようなものです。

GET /ws/schools/7/students/updates?since={seq}

サーバー側システムの開始以来、一連の更新があり、上記の形式のリクエストは、シーケンス値が より大きい最初の N 個の更新を取得すると思います{seq}。このようにして、クライアントが非常に遅れて追いつく必要がある場合、結果はページングされます.

于 2014-10-14T15:30:28.680 に答える