面接官が評価するポイント
マルチテナントAPIにおいて、ゲートウェイ、アプリケーション、非同期ジョブからエラーが出力されるため、クライアントが障害を一貫して解析できません。RFC 9457を使用して共有エラーコントラクトを設計し、ステータスコード、メディアタイプ、type URI、一括バリデーション、リトライ、マスキング、バージョン互換性について説明してください。
コンテキストと制約条件
- リクエストはCDN、APIゲートウェイ、ビジネスサービス、キューを通過する可能性があります。
- クライアントは、修正可能な入力エラー、認可エラー、レート制限(スロットリング)、一時的な障害を区別できる必要があります。
- 詳細情報にスタックトレース、キー、テナント分離データ、内部ホスト名を露出させてはなりません。
- 既存クライアントはレガシーフィールドを解析しているため、移行は後方互換性を維持する必要があります。
HTTPセマンティクスとビジネス詳細の分離
HTTPステータスはプロトコルレベルの結果を表し、Problem Detailsのボディはその原因を説明します。すべての障害に対して200を返すのではなく、セマンティクスに従って400、401、403、404、409、429、5xxを選択します。機械的な分類にはtypeに安定したURIを使用し、表示用のtitle、リクエスト固有のdetailを使用します。
最小限の拡張可能なコントラクトの定義
コアメンバーはtype、title、status、detail、instanceです。フィールドエラー用のerrorsや、クライアント待機ヒント用のretryAfterなど、拡張メンバーは明示的に名前を付けます。各タイプのドキュメントには、その意味、許可されるステータスコード、クライアントのアクションを記載する必要があります。クライアントは自然言語のタイトルで条件分岐してはなりません。
レイヤー間でのエラー境界の共有
ゲートウェイが生成するタイムアウト、認証、スロットリングのエラーは同じメディアタイプを使用しますが、アプリケーションのビジネスタイプになりすましてはなりません。サービスはテレメトリ用に内部エラーコードを保持しつつ、承認されたタイプのみを公開します。機密性の高い詳細テキストをコピーすることなく、サービス間で相関ID(correlation ID)を伝播させます。
回答前の確認質問
- クライアントはステータス、
type、またはレガシーなcodeで分岐していますか? これにより移行アダプターが決まります。 - 1つのレスポンスに複数のフィールドバリデーションエラーを含めることはできますか? これにより
errorsの構造と順序の保証が決まります。 - ゲートウェイはビジネスエラーを理解できますか、それともインフラエラーの転送と生成のみを行いますか? これによりタイプの所有権が決まります。
30秒の回答フレームワーク
「正しいHTTPステータスを維持し、安定したtype、title、status、detail、およびオプションのinstanceを含むapplication/problem+jsonを返します。クライアントはステータスとtypeに基づいて分岐し、散文テキストでは決して分岐しません。ゲートウェイは自身のエラータイプのみを所有します。バリデーション、リトライヒント、相関ID、マスキングルールは、互換性マトリクスと実際のリクエストパスを通じて検証されるバージョニングされたコントラクトになります。」
ステップバイステップの詳細解説
まずはエラータイプレジストリの作成から始めます。各タイプにはURI、公開メンバー、許可されるステータス、クライアントのアクション、セキュリティレベルが設定されます。バリデーションエラーは400を使用し、フィールドごとの問題をerrors配下に配置します。認証情報の欠落や権限不足は401および403のままとし、楽観的排他制御の競合には409、スロットリングには実行可能な待機ヒントを伴う429、不明な障害には500または503と汎用パブリックタイプを使用します。
Content-Typeは表現と整合性を保ちます。instanceの値はサポートのために特定のリクエストを識別できますが、detailに完全なURL、SQL、スタックトレース、テナント識別子を含めてはなりません。ログには内部原因、相関ID、セキュリティ監査フィールドを保持し、クライアントにはポリシーでフィルタリングされたコンテンツのみを返します。
一括バリデーションでは、複数の問題が許可されるかどうか、フィールドパスの記述方法、最大エントリ数を定義します。クライアントは未知の拡張メンバーを無視します。新しいメンバーは追加のみとし、既存のtypeの意味を変更する場合は新しいURIが必要です。非同期ジョブは、キューの内部情報を同期的に漏洩させるのではなく、ジョブリソースを通じてその失敗を公開します。
模範解答
「タイプレジストリを維持し、ゲートウェイ、同期サービス、非同期ジョブがRFC 9457準拠のapplication/problem+jsonを出力するようにします。ステータスはプロトコルのセマンティクスを伝え、typeは安定したカテゴリを伝え、detailはこのリクエストのみを説明します。フィールドバリデーションには上限を設定したerrors拡張を使用し、429には解析可能な待機ヒントを含め、500と503には汎用パブリックタイプを使用しつつスタックトレースはログに残します。移行期間中はレガシーなcodeを維持し、コントラクトテスト、互換性マトリクス、マスキング監査を通じてクライアントを切り替えます。」
よくある間違い
- ビジネスエラーフィールドを含めつつ200を返し、キャッシュ、監視、リトライ処理に成功と誤認させること。
titleまたはdetailで分岐処理を行い、翻訳や文言の変更によってクライアントを破損させること。- 各サービスが独自に
typeのURIを作成することを許可し、一貫した集約を妨げること。 detailにスタックトレース、SQL、内部ドメイン、完全なテナント識別子を返すこと。- ゲートウェイのタイムアウトをビジネスエラーに変換し、誤ったリトライやユーザーガイダンスを引き起こすこと。
障害の兆候と修正
クライアントがリトライすべきかどうか判断できない場合、通常はステータス、タイプ、リトライガイダンスが一致していません。まずレジストリを構築し、すべてのレイヤーを少数のパブリックセットにマッピングし、未知のタイプに対する安全なデフォルトを定義し、相関IDで内部原因を追跡します。
本番環境での実装
サービスの境界でステータスの選択を維持しながら、シリアライズ処理を共有ライブラリまたはエッジアダプターに集約します。スキーマバリデーションによって拡張の長さ、配列の要素数、URI形式を制限し、ゲートウェイだけに依存するのではなくシリアライズ前にマスキングを行います。リトライの嵐(retry storm)を防ぐため、429、503、ネットワークタイムアウトに対して、エクスポネンシャルバックオフ、ジッター、冪等性の条件を個別に定義します。
検証チェックリスト
コントラクトテストでは、すべてのパブリックタイプのステータス、メディアタイプ、必須メンバー、拡張をカバーします。統合テストではゲートウェイ、サービス、キューを横断し、相関IDとマスキングを検証します。互換性テストではレガシークライアントを使用して、未知のメンバーに対する許容性と保持されたcodeを検証します。負荷テストでは、シリアライズのレイテンシ、ログサンプリング、スロットリング下でのリトライ増幅を測定します。
フォローアップ質問と回答
なぜ単一のビジネスエラーコードを定義しないのですか?
単一のコードでは、HTTPキャッシュ、認証、スロットリング、リトライのセマンティクスを表現できません。ステータスにより汎用インフラストラクチャが正しく動作し、typeが安定したビジネスカテゴリを伝達します。両者には異なる責任があります。
typeのURIはアクセス可能である必要がありますか?
仕様では相対URIまたは絶対URIが許可されています。安定的で文書化可能な形式を選択しますが、ドキュメントページの可用性をクライアントの処理前提にしてはなりません。
エラーボディからのデータ漏洩をどのように防ぎますか?
パブリックメンバーの許可リスト、長さの制限、機密パターンのスキャンを使用します。内部例外を汎用タイプにマッピングし、サポート用には相関IDのみを保持します。セキュリティテストでは、テナント間クエリ、認可障害、例外パスをカバーします。
採点ルーブリック
- セマンティクスの正確性:HTTPステータスの意味とProblem Detailsメンバーを区別できているか。
- コントラクト設計:安定したタイプ、拡張、バージョニングを提案できているか。
- 境界の認識:ゲートウェイ、ジョブ、マスキング、リトライの嵐をカバーできているか。
- 実装可能性:レジストリ、シリアライズ境界、互換性マトリクス、テストが含まれているか。
- リスク管理:情報漏洩を回避し、デフォルトで未知のタイプをリトライ可能として扱わないようにしているか。
コンプライアンスチェック
ステータスコード、タイプフィールド、マスキング、リトライ境界の一貫性が維持されていることを確認します。
面接回答チェックリスト
ステータスのセマンティクスから始め、typeが機械的に安定した識別子であり、detailがコントラクトキーではないことを説明します。ゲートウェイの所有権、バリデーション、リトライ、マスキング、互換性の根拠を追加します。
1行のまとめ
ステータスでプロトコルのセマンティクスを表現し、typeで安定した分類を表現し、拡張で実行可能な詳細を表現し、セキュリティと互換性のテストで境界を保護することによってエラーを標準化します。