プロンプトとスコープ
ある API が大きな JSON ドキュメントを返し、クライアントが前回の ETag を保存しています。HTTP 226 IM Used が適切となるタイミング、クライアントとサーバーが交換するヘッダー、および差分が適用できない場合に正確性がどのように維持されるかを説明してください。ネゴシエーション、キャッシング、フォールバックを網羅してください。特定の diff アルゴリズムは不要です。
面接官がテストしていること
- 226 が GET に対する差分を表すものであり、任意の不完全な成功ではないことを知っているか。
A-IM、IM、ETag、およびオプションのDelta-Baseを 1 つのやり取りに結び付けられるか。- ベースバージョン、キャッシュの並行性、アルゴリズムのコスト、および完全な 200 の境界を特定できるか。
- デプロイ前にクライアント、中間機器(プロキシ)、およびキャッシュでのサポートを検証するかどうか。
明確化のための質問
- クライアントはネゴシエートされたインスタンス操作アルゴリズムを適用できますか?
- ドキュメントは安定した ETag によって厳密に識別されており、差分生成はその CPU コストに見合っていますか?
- プロキシはレスポンスを書き換えたりキャッシュしたりしますか?また、差分のセマンティクスを維持できますか?
- ベースが古くなっているか無効である場合、クライアントは透過的に完全な表現を取得できますか?
30秒での回答
私は 226 をオプションのネゴシエートされた最適化として扱います。クライアントは A-IM とベース表現の If-None-Match を送信します。サーバーは、アルゴリズムをサポートし、かつその正確なベースを保持している場合にのみ 226 を返し、IM でアルゴリズムを宣言し、新しい ETag を返し、有用な場合は Delta-Base を返します。クライアントはベースタグを検証し、差分を適用し、結果として得られたエンティティタグを検証します。不一致、不十分な費用対効果、サポートされていないクライアント、またはマージの失敗が発生した場合は、完全な 200 にフォールバックします。キャッシュは、ベースとレスポンスのメタデータが一致する場合にのみ差分を再利用する必要があります。
ステップごとの設計
1. 差分機能のネゴシエーション
A-IM はクライアントが受け入れ可能なインスタンス操作アルゴリズムを一覧表示し、サーバーは IM で選択したものを指定します。これはコンテンツエンコーディングによる圧縮とは異なります。圧縮は転送コーディングを変更しますが、差分は表現の生成方法を変更します。相互にサポートされているアルゴリズムがない場合は、200 を使用します。
2. ベースをバージョンにバインドする
クライアントはローカルのエンティティタグを識別するために If-None-Match を使用します。サーバーは、タイムスタンプやクライアント提供のバージョンから推測するのではなく、そのタグがベース表現にマップされていることを確認する必要があります。レスポンスには新しい ETag が含まれます。Delta-Base はベースタグを明示的に識別できます。クライアントは、マージされた結果を新しいタグに対して検証します。
3. フォールバックを安全にする
ベースが存在しない、差分がドキュメント全体よりも大きい、アルゴリズムがタイムアウトする、マージの検証に失敗する、または中間機器が安全でない場合は、200 を返します。クライアントは使用できないベースを破棄して再同期する必要があり、これにより不正な差分が以降の更新を汚染することを防ぎます。サイズ、CPU、および時間のバジェットを適用します。
4. キャッシュキーとメトリクスをプロトコルの一部として扱う
キャッシュキーには、URL、ネゴシエーションヘッダー、およびベースを選択する条件を含める必要があります。ある ETag に対して有効な差分は汎用的なレスポンスではありません。226 のヒット率、差分と完全なバイト数の比較、マージの失敗、フォールバック率、および生成レイテンシを測定して、最適化がその複雑さに見合っていることを証明します。
質の高い模範解答
私は明示的なフォールバックを備えた最適化としてリリースします。クライアントはサポートされている A-IM アルゴリズムを通知し、そのベースの If-None-Match を送信します。サーバーはベースが存在し、アルゴリズムが許可リストに含まれていることを確認し、差分サイズと生成コストを比較します。その場合にのみ 226 を返し、IM でアルゴリズムを宣言し、結果の新しい ETag を発行し、オプションで Delta-Base を使用してベースを識別します。クライアントはベースタグを検証し、差分を適用し、ドキュメントを置き換える前に新しいエンティティタグを検証します。バージョンの不一致、サイズ超過の差分、マージの失敗、またはサポートされていないパスがある場合は、200 を返します。キャッシュはネゴシエーションとベース条件によって Vary され、テレメトリは節約されたバイト数、CPU、障害、およびフォールバックを記録します。差分のサポートにより、正確性の前提条件となることなく転送効率が向上します。
よくある間違い
- 206 は Range リクエストに応答するものであるにもかかわらず、226 を 206 と同様に扱うこと。
- ETag で正確なベースをバインドする代わりに、非公式なバージョン番号のみを送信すること。
- すべてのブラウザ、プロキシ、およびキャッシュが差分セマンティクスを理解していると思い込むこと。
- 差分のサイズとドキュメント全体のサイズの比較を省略すること。
- マージ失敗後に再同期せず、無効なベースから処理を続行すること。
- 圧縮、JSON Patch、および RFC 3229 インスタンス操作を同じプロトコル層として扱うこと。
フォローアップの質問と回答
226 は 206 や 304 とどのように異なりますか?
206 は Range で要求されたバイト範囲を返します。304 は条件付きリクエストに対して新しい表現が不要であることを示します。226 は既存の表現に基づく差分を返します。リクエスト条件、クライアントの処理、およびキャッシュセマンティクスが異なります。
ベース ETag が古い場合はどうなりますか?
差分を盲目的に適用しないでください。完全な 200 を返すか、クライアントに現在のベースを取得させ、使用できないローカルベースを破棄し、完全な表現からキャッシュを再構築させます。
差分キャッシュの汚染をどのように防ぎますか?
URL、ネゴシエートされたアルゴリズム、ベース ETag、およびレスポンス ETag をバインドします。IM と Delta-Base を検証します。中間機器が別のベースに対して差分を再利用するのを防ぎ、マージされたエンティティの整合性を検証します。