1. プロンプトとシナリオ
注文 API が JSON リクエストを受け付けます。クライアントは、構文的には有効でもフィールド間の関係が無効なデータを送信したり、古いバージョンから注文を更新したり、すでに存在するユーザー名を作成しようとしたりする可能性があります。クライアントがリクエストを編集すべきか、リソースを再読み込みすべきか、リトライを中止すべきかを判断できるように、409 と 422 の境界を定義してください。
2. 面接官がテストしているポイント
- 処理不可能なリクエストセマンティクスと、現在のリソース状態との競合を明確に区別できているか。
- 変更されていない 422 リクエストを再試行しても通常は同じ結果になることを理解しているか。
- 同時実行制御、冪等なリトライ、エラーコントラクトを関連付けて考えられているか。
- 隣接する 400 や 412 のレスポンスを適切に位置づけ、ポリシーの一貫性を維持できるか。
3. 確認すべき質問
- API は ETag、バージョン番号、またはその他の楽観的同時実行制御メカニズムを使用していますか?
- 「名前がすでに存在する」はフィールドのバリデーションルールとしてモデル化されていますか、それともコレクションの現在の状態としてモデル化されていますか?
- クライアントはリソースを再読み込みして、ユーザーに差分を表示できますか?
- チーム内でエラーコード、フィールドパス、リトライ動作はすでに標準化されていますか?
4. 30秒の回答フレームワーク
まずは原因を分類します。サーバーがメディアタイプと構文を理解できるものの、リクエストのセマンティクスを処理できない場合は 422 を返します。理解可能なリクエストが対象リソースの現在の状態と競合する場合は 409 を返します。パースできないリクエストには 400 を使用し、条件付きリクエストの事前条件が満たされないことが明確な規約である場合は 412 を使用します。最後に、機械可読なコード、修正ガイダンス、バージョン情報を含めます。
5. ステップ別の解決策
ステップ 1: 422 の境界を定義する
422 は、コンテンツタイプと構文は理解できるものの、含まれている指示を処理できないことを意味します。例としては、開始日より前の終了日、許可されていない enum 値、無効なフィールドの組み合わせなどが挙げられます。この失敗は通常、誰が最後にリソースを変更したかには依存しないため、クライアントはペイロードを修正してから再送信する必要があります。
ステップ 2: 409 の境界を定義する
409 は、リクエストが対象リソースの現在の状態と競合していることを意味します。典型的な例としては、古いバージョンに基づく更新、出荷済み注文のキャンセル、既存の一意なリソースと重複するリソースの作成などがあります。安全であれば、現在のバージョン、競合の種類、および具体的な次のステップを含めます。
ステップ 3: 隣接するステータスコードを位置づける
リクエストをパースするために必要な構文が壊れている場合や JSON が不正な場合は 400 を使用します。If-Match を含み、指定された条件を満たさないリクエストには 412 を使用できます。これは、すべての条件付きエラーを 409 と呼ぶよりも正確です。各エンドポイントが互換性のない意味を作り出さないように、選択したポリシーを文書化します。
ステップ 4: リトライとエラーボディの設計
変更されていない 422 ペイロードは再度失敗することが予想されるため、自動的にリトライしないでください。409 は修正可能な場合があります。競合の種類が許容する場合は、再読み込み、マージ、再試行を行いますが、盲目的にループさせることは避けます。安定した code、フィールドパスまたはリソース識別子、現在のバージョン、修正ガイダンスを返します。認証情報やその他の機密情報はレスポンスやログに含めないようにします。
6. 模範回答
私は障害をペイロードのセマンティクスの問題か、リソース状態の競合(レースコンディション)かで分類します。前後が逆の期間、無効な enum、あり得ないフィールドの組み合わせなどは 422 です。サーバーがリクエストを理解したものの、すでに出荷された注文、古いバージョン、既存の一意なリソースを検出した場合は 409 を返すことができます。不正な JSON は 400 であり、満たされなかった If-Match 条件は 412 になります。
>
422 に対しては、クライアントがデータを編集できるように安定したビジネスコードとフィールドパスを返します。409 に対しては、クライアントが再読み込みしてマージ、破棄、またはリトライを選択できるように、競合の種類とサーバーのバージョンまたは状態を返します。どちらのステータスも無条件のリトライを引き起こすべきではありません。冪等性キーは重複実行を防ぎますが、同時実行の競合を解消するわけではありません。すべてのエンドポイントで単一のポリシーを文書化し、各エラーがどのように修復されるかを監視します。
7. よくある間違い
- すべてのビジネスバリデーションエラーに 409 を返し、リソースを再読み込みすれば修正されると誤認させること。
- バージョン競合に 422 を返し、状態が変更されたというシグナルを隠してしまうこと。
- いずれのステータスに対しても無制限の自動リトライを追加し、リクエストの嵐(request storm)を引き起こすこと。
- 安定したコード、フィールドパス、または修正方針を示さず、人間向けのメッセージのみを返すこと。
- ペイロードルールなのかリソース状態の競合なのかを定義せずに、すべての「重複」に対して単一のコードを選択すること。
8. フォローアップ質問と回答
フォローアップ 1: ユーザー名の重複は 409 と 422 のどちらにすべきですか?
一意性がコレクションの現在の状態としてモデル化されている場合、409 は状態の競合を伝えます。チームがこれをフィールドセマンティクスのバリデーションとしてモデル化している場合は、422 でも一貫性を保てます。普遍的なラベルよりも、安定したコントラクトと予測可能なクライアント動作のほうが重要です。
フォローアップ 2: すべての 409 はリトライ可能ですか?
いいえ。バージョン競合はマージ後にリトライできる場合がありますが、出荷済み注文のキャンセルは処理を停止して現在の状態を表示する必要があります。レスポンスでは、競合が修復可能かどうかを伝える必要があります。
フォローアップ 3: 422 で権限エラーを表すことはできますか?
認証および認可のセマンティクスを置き換えるべきではありません。認証の欠如は通常 401 であり、権限のない認証済み呼び出し元は通常 403 です。422 はセマンティクスを処理できないコンテンツ専用として保持してください。