設問とスコープ
これは API 境界におけるプロトコル設計をテストするものです。参照されている文書は 2026 年 5 月 23 日に公開された有効な Internet-Draft であり、RFC ではありません。それを利用する前にそのステータスを明記してください。この設計は、デプロイメントが提案の一部のみを採用した場合でも安全であり続ける必要があります。
面接官が評価するポイント
- ポリシーのメタデータと現在利用可能なクォータとの正確な区別。
- Structured Fields のパース、複数のウィンドウ、クォータ単位、およびパーティションキー。
- 429、Retry-After、ゲートウェイ、CDN、および古いキャッシュレスポンスとの相互作用。
- リミットを公開することによるプライバシーおよび DoS(サービス運用妨害)リスク。
- ヒントを拘束力のないものとして扱い、フィールドの欠落や不正なフォーマットを許容するクライアントのバックオフ。
推奨される回答の構成
まずクォータのディメンションと所有権を定義します。ポリシーと現在のリミットを含む 1 つのレスポンスを示し、次にクライアントがどのように処理をスケジュールするかを説明します。キャッシュと仲介者のルール、セキュリティ制約、可観測性、そしてドラフトがクライアントを破損させることなく変更できるようにするための機能フラグ(feature flag)を用いたロールアウト計画を追加します。
詳細解説:キャパシティを保証することなくヘッダーを有用にする
ポリシーと現在の状態の分離
RateLimit-Policy は "tenant";q=1000;w=60 などの名前付きクォータを記述します。RateLimit は "tenant";r=420;t=23 のように、利用可能なクォータと有効なウィンドウを報告します。ポリシーには複数のアイテムや可変ウィンドウを含めることができます。サーバーが常に権威を持ちます。これらの値はヒントであり、リースやサービスレベルの保証ではありません。
パーティションと単位のセマンティクスの定義
1 つのクォータ単位がリクエスト、バイト、トークン、または重み付けされたオペレーションのどれを意味するかを文書化します。パーティションキーはテナントやリソースを区別する場合がありますが、ヘッダーにメールアドレス、生のユーザー ID、またはシークレットを決して含めてはなりません。ポリシー名は安定させ、バージョン管理を行ってください。ポリシー識別子を変更せずに単位を変更すると、クライアントのペーシング(送信間隔の調整)が安全でなくなります。
429 と Retry-After の調整
拒否されたリクエストをいつ再試行できるかをサーバーが把握している場合は、Retry-After を返します。両方のフィールドが存在する場合、クライアントは Retry-After を優先します。RateLimit は将来の処理のペース調整に役立ちます。このドラフトは特定の制限アルゴリズム(throttling algorithm)を要求していないため、クライアントには上限付きの指数バックオフ、ジッター、デッドライン、および書き込みに対する冪等性ルールが引き続き必要です。
キャッシュと仲介者を関係者として扱う
キャッシュされたレスポンスの RateLimit の値は古い可能性があり、レスポンスの現在の経過時間(current age)が正である場合は無視する必要があります。クォータのセマンティクスを認識していない仲介者は、レスポンスを実際より寛容に見せてはなりません。より厳しい制限を適用するゲートウェイはその厳格なポリシーを伝達できますが、テレメトリはオリジンとゲートウェイの決定を別々に記録します。
可用性とプライバシーの保護
トラフィック量を露呈させたり、攻撃者がリクエストを増幅させたりするような大きなクォータウィンドウを公開しないでください。利用可能なクォータと有効なウィンドウの比率に上限を設け、受信した Structured Fields を検証し、不正な値は無視します。飽和時にアドバタイズする値を下げることは許可されますが、クライアントは直近のヒントが健全に見えた場合でも拒否を処理できなければなりません。
回答例
「テナントおよび操作ごとに名前付きポリシーのバージョンを管理し、単位を定義した上で、ポリシーのメタデータを現在の残りクォータとは個別に発行します。この仕様は Internet-Draft であるため、クライアントは両方のフィールドをオプションのヒントとして扱います。Retry-After は拒否されたリクエストを制御し、RateLimit は将来の作業のペースを調整します。CDN はキャッシュされた値を古いものとしてマークし、ゲートウェイがオリジンの制限を緩く見せることは決してなく、パーティションキーには識別子を含めません。SDK は Structured Fields を防御的にパースし、ジッターと共有キューを使用し、コントラクトを段階的に有効化する前に、アドバタイズされたリミットと適用されたリミットのメトリクスを公開します。」
よくある失敗パターンと対策
- ドラフトを RFC と呼ぶ → その Internet-Draft ステータスを記録し、バージョン管理されたコントラクトの背後に分離する。
- 残りクォータを許可として使用する → ヒントとして扱う。サーバーは飽和時に拒否する可能性がある。
- パーティションキーでユーザー識別子を返す → 不透明でカーディナリティの低い名前を使用し、プライバシーの露出を見直す。
- キャッシュされたヘッダーを信頼する → 古い値を無視し、オリジンにリミットを適用させる。
- すべての 429 を即座に再試行する →
Retry-Afterを尊重し、ジッターを追加し、メソッド固有の冪等性を強制する。
評価基準とセルフチェック
ポリシーと状態の分離、単位とパーティション、429 との相互作用、キャッシュの動作、プライバシー、クライアントのペーシング、ロールアウトの安全性、およびメトリクスを評価します。優れた回答は、各ヘッダーの意味、それが保証できないこと、そしてフィールドが存在しない、古い、または不正な形式である場合にクライアントがどのように動作するかを説明しています。
フォローアップと発展課題
レスポンスに 2 つのウィンドウがある場合はどうなりますか?
ペーシングには最初に枯渇する制約を選択しつつ、可観測性のためにすべてのアイテムを保持します。SDK は、異なる単位やパーティションキーを持つウィンドウを警告なしに統合(collapse)してはなりません。
成功したレスポンスに RateLimit を含めるべきですか?
含めても構いませんが、クライアントはすべてのレスポンスにそれが含まれていると想定してはなりません。製品にとって有用な場合にのみ出力し、キャッシュが古い値を現在の約束に変えてしまわないようにします。
変更されるドラフトをどのようにロールアウトしますか?
ヘッダープロファイルまたはポリシーバージョンをネゴシエーションし、パーサーのフォールバックをログに記録し、SDK バージョンごとにカナリアリリースを行い、新しいフィールドがオプションである間も 429 と Retry-After の動作を安定させます。
コントラクトが機能していることを証明するメトリクスは何ですか?
ゲートウェイおよび SDK バージョンごとに、アドバタイズされたリミットと強制されたリミット、古いヘッダーによる決定、429 レート、再試行の増幅、キュー遅延、最終的な成功、およびプライバシーに配慮したパーティションのカーディナリティを追跡します。