プロンプトとスコープ
バッチ書き込みAPIは、帯域幅とレイテンシの目標が異なるクライアントに対応します。ステータスのみを必要とするクライアント、完全なリソース表現を必要とするクライアント、ポーリングを避けるために数秒待機するクライアントがあります。RFC 7240を使用して、Preferリクエストヘッダー、Preference-Appliedレスポンスヘッダー、エラーハンドリング、キャッシング、およびフォールバック動作を設計してください。
Preferはリクエストの優先設定(preference)であり、サーバーへの強制ではありません。この質問はプロトコルのセマンティクスとAPIコントラクトをテストするものであり、すべてのプロキシが優先設定ヘッダーを維持することを前提とはしていません。
面接官がテストしていること
- クライアントの優先設定とサーバーの保証を区別し、実際に適用されたものを報告できるか。
return=minimal、return=representation、respond-async、およびwaitを正しく使用しているか。- レスポンスバリアント、
Vary、キャッシュキー、およびプロキシの互換性を考慮しているか。 - 優先設定が適用されない場合でも、リトライ、冪等性キー、および非同期ジョブの状態が安全に保たれるか。
明確化のための質問
- このAPIは安全な読み取りですか、それとも副作用を伴う書き込みですか?また、すでに冪等性キーを持っていますか?
- 完全なリソース表現のサイズ、生成コスト、および最大待機時間はどれくらいですか?
- クライアントは202およびステータスリソース、ポーリング、またはコールバックを受け入れられますか?
- ミドルボックスはPreferを転送しますか?また、キャッシュは共有可能ですか?
- 優先設定が適用されない場合、クライアントはどの安定したフィールドを確認する必要がありますか?
30秒の回答
「Preferは、サーバーが無視または部分的に適用できるクライアントの優先設定を表明し、Preference-Appliedは実際に適用された内容を報告します。書き込みではreturn=minimalを使用してレスポンスを削減でき、同期呼び出し元はreturn=representationをリクエストでき、時間のかかる処理では制限付きのwaitとともにrespond-asyncを使用できます。私なら、冪等性キー、202ステータスリソース、キャッシュのVary、およびクライアントのフォールバックを組み合わせて設計します。Preference-Appliedがない場合はデフォルトのレスポンスをパースし、優先設定が成功したと決して想定しません。」
ステップバイステップの設計
1. 優先設定を無視可能なネゴシエーションとして扱う
RFC 7240はPreferリクエストヘッダーとPreference-Appliedレスポンスヘッダーを定義しています。サーバーは優先設定を拒否できるため、ボディとステータスコードには安定したデフォルトのコントラクトが必要です。クライアントは単にPreferを送信したというだけでパース処理を省略してはなりません。
2. 適切な優先設定トークンを選択する
return=minimalは確認のみを必要とする書き込みに適しており、return=representationは更新されたリソースを必要とする同期呼び出し元に適しています。respond-asyncはクライアントが非同期処理を受け入れることを示し、wait=nは待機許容時間(バジェット)を提供します。これらはヒントであり、SLAの保証ではありません。
3. レスポンスで結果を確認する
優先設定が使用された場合はPreference-Appliedを送信します。使用されない場合、このヘッダーは存在しない可能性があり、デフォルトのコントラクトが適用されます。非同期パスは202、ステータスURI、および追跡可能なIDを返します。同期待機バジェットが切れた後も、操作はクエリ可能な状態のまま維持され、クライアントが副作用を再送信するのを防ぎます。
POST /v1/imports HTTP/1.1
Prefer: return=minimal, respond-async, wait=3
Idempotency-Key: imp-8f2
HTTP/1.1 202 Accepted
Preference-Applied: respond-async
Location: https://api.example/imports/jobs/42
Cache-Control: no-store4. キャッシュバリアントを処理する
安全なGETリソース表現がPreferによって異なる場合は、Varyを正しく宣言するか、優先設定に依存するレスポンスを共有キャッシュから除外します。通常、書き込みにはno-storeを使用します。非同期ステータスリソースは、ミドルボックスが古い進行状況を返さないように、短いキャッシュ、ETag、または明示的なポーリング条件を定義する必要があります。
5. 冪等性とフォールバックを維持する
Preferは操作のセマンティクスを変更しないため、リトライには引き続き冪等性が必要です。書き込みには冪等性キーまたはビジネス重複排除キーを使用します。クライアントが202、タイムアウト、またはPreference-Appliedがないことを確認した場合は、リソースを再作成するのではなく、ジョブをクエリするか、デフォルトのレスポンスコントラクトに従う必要があります。
6. オブザーバビリティと制限を設定する
優先設定トークン、適用されたかどうか、待機時間、レスポンスサイズ、202の発生率、およびプロキシパスを記録します。waitを制限し、過大な値は拒否または切り詰めます。任意のクライアント文字列を高コストな実行パスに変換するのではなく、不明な優先設定は無視して記録します。
質の高い模範解答
「私はPreferを保証ではなく、無視可能なクライアントの優先設定として扱います。書き込みはデフォルトで安定したステータスになり、小さなレスポンスを求めるクライアントはreturn=minimalを送信し、リソースを必要とするクライアントはreturn=representationを送信し、時間のかかるジョブは制限付きのwaitとともにrespond-asyncを使用します。サーバーは優先設定を適用した場合にのみPreference-Appliedを送信します。非同期の結果はLocationとジョブIDを含む202になります。書き込みには冪等性キーを使用し、レスポンスには必要に応じてno-storeを使用し、リソース表現の違いはVaryまたはキャッシュポリシーで分離します。Preference-Appliedがない場合、クライアントはデフォルトのパーサーに従い、ジョブをクエリして、副作用を決して重複させません。」
よくある間違い
- Preferを必須として扱う → サーバーやプロキシが無視する可能性がある → デフォルトのコントラクトとPreference-Appliedを使用する。
- waitを完了の保証として扱う → 時間のかかるジョブはそれを超える可能性がある → バジェットを制限し、202ステータスリソースを公開する。
- 非同期タイムアウト後に再送信する → 副作用の重複が発生する → 冪等性キーを使用し、最初にクエリを実行する。
- キャッシュバリアントを無視する → クライアントが不一致なリソース表現を受け取る → Varyを設定するか、キャッシュを分離する。
- 任意の不明な優先設定を実行する → 攻撃者がリソースコストを増大させる可能性がある → トークンを無視し、記録し、制限する。
フォローアップの質問と回答
Preference-Appliedがないことはリクエストが失敗したことを意味しますか?
いいえ。サーバーがデフォルトの動作を選択したか、優先設定を無視した可能性があります。クライアントは安定したデフォルトコントラクトをパースすべきであり、プロトコルまたはビジネス状態が失敗を示している場合にのみ失敗とみなします。
すべての書き込みでreturn=minimalを使用できますか?
いいえ。これはクライアントが完全なリソース表現を必要としないことを示すだけです。クライアントがサーバー生成のバージョン、ダイジェスト、または次のリンクを必要とする場合は、空のレスポンスからフィールドを推測するのではなく、表現をリクエストするかリソースを取得する必要があります。
wait=5によりサーバーは確実に5秒間ブロックされますか?
厳格な保証はありません。これはクライアントの最大待機希望時間です。サーバーはより早く完了するか、無視するか、非同期に切り替えることがあります。サーバーのタイムアウト、同時実行数の制限、およびリソースバジェットが引き続き適用されます。