代表的な面接トピック

プロダクト面接:SaaSはIdempotency-Keyのサポートを保証すべきか?

プロダクト難しい
Offer.cc 編集チーム公開日 更新日

質問

ネットワークタイムアウト後、顧客は作成リクエストを再送します。SaaS APIにおいてIdempotency-Keyのサポートを提供し、保証しますか?

プロンプトとコンテキスト

決済、チケット発行、リソース作成のAPIでは、リクエストが実行されたにもかかわらず、そのレスポンスが失われることがあります。顧客は安全にリトライを行うためにIdempotency-Keyを求めています。これをリリースすべきかどうかを判断し、約束事項、対象顧客、メトリクス、コスト、ロールバック計画を定義してください。

面接官が見ているポイント

プロトコルレベルの機能を、検証可能なプロダクトコントラクト(対応操作、キーの有効期間、パラメータ不一致時の挙動、重複レスポンス、および信頼性・ストレージコスト・開発者体験のトレードオフ)へと昇華させられるかどうかを評価しています。

明確にすべき質問

問題となっている副作用が重複請求なのか、重複リソースなのか、それとも重複通知なのかを明確にします。次に、リクエスト量、リトライウィンドウ、マルチリージョンの要件、保持ルールについて確認します。提供する約束が根拠のない「exactly-once(正確に1回)」の主張にならないよう、サーバー側の重複排除とビジネス処理の完了を切り離して考えます。

30秒の回答

「すべてのエンドポイントでexactly-onceを保証するのではなく、リスクの高い書き込み操作に限定した冪等性を提供します。コントラクトでは、キーのフォーマット、テナントスコープ、保持期間、パラメータのフィンガープリント、重複レスポンスを定義すべきであり、同じキーで異なるパラメータが渡された場合は競合(コンフリクト)とする必要があります。まずは決済とリソース作成で試験導入し、重複副作用の発生率、安全なリトライの成功率、ストレージコスト、サポート件数を測定した上で、明確な409/422セマンティクスを持つオプトイン方式のカナリアリリースを通じて拡大します。」

ステップごとの詳細解説

ユーザー価値の定義

「タイムアウト後に安全にリトライできること」を成果とし、金銭的またはリソース的な副作用を伴うPOST操作を優先します。読み取り専用の呼び出しや、本質的に冪等であるPUT操作に対しては、マーケティング的な理由でこのような複雑さを導入する必要はありません。

コントラクト境界の策定

テナント単位での一意性、長さの制限、保持期間、リトライ可能な状態を定義します。最初のステータスとボディを保存します。誤った結果が暗黙的に再利用されるのを防ぐため、同じキーでパラメータが異なる場合は競合を返す必要があります。

ビジネストランザクションとの連携

重複排除レコードは、副作用を伴う処理と信頼性の高いトランザクションを共有するか、リカバリ可能なアウトボックスパターンを使用する必要があります。キャッシュヒットはダウンストリームでの処理完了を証明するものではありません。非同期処理の場合は、問い合わせ可能な操作IDを返す必要があります。

エラー設計と互換性

進行中(in-progress)、成功(succeeded)、失敗(failed)、期限切れ(expired)を明確に区別します。SDK、ドキュメント、ゲートウェイはキーを一貫して転送する必要があります。既存のクライアントは引き続き動作可能としますが、暗黙的なリトライ保証が適用されるべきではありません。

メトリクスとコストの選定

プライマリメトリクスとして重複副作用率と安全なリトライ成功率を追跡します。ガードレールメトリクスには、キーストアの容量、P95レイテンシ、競合率、サポートボリュームが含まれます。レスポンスを永久に保持するのではなく、テナントのリスクに応じてTTLとストレージを設定します。

段階的なロールアウト

単一リージョン、決済サンドボックス、内部SDKから開始します。シャドウ重複排除ログでヒット率を検証し、少数のテナントコホートにオプトインさせます。レスポンスの不一致が発生した場合、ストレージが無秩序に増大した場合、またはダウンストリームでトランザクションがサポートされていない場合は、既存のパスを維持したまま新しいエントリポイントを無効化します。

模範解答

私はIdempotency-Keyを高リスクな書き込みに対する「リトライ安全性コントラクト」として位置づけます。決済とリソース作成から着手し、テナントスコープ、キーのフォーマット、保持期間、パラメータのフィンガープリント、重複レスポンスを定義します。パラメータが競合する場合はエラーを返し、非同期の副作用には問い合わせ可能な操作IDを提供します。重複副作用、安全なリトライの成功率、P95レイテンシ、競合率、ストレージコストを測定します。サンドボックスおよびオプトインカナリアで試験導入し、トランザクションやダウンストリームのサポートが不足している場合は約束の適用範囲を広げないようにします。

よくある間違い

exactly-onceを約束してしまう

Idempotency-Keyは主にクライアントからの重複送信を排除するものであり、リカバリ不能なダウンストリームの副作用までカバーすることはできません。at-most-once(最大1回)の処理と最終状態の照会について明示的に説明してください。

キーを永久に保持する

永続的な保持は、コスト、プライバシー、クリーンアップの問題を引き起こします。リスクに応じてTTLを定義し、期限切れ後の動作を文書化してください。

パラメータの変更を無視する

異なるリクエストに対して最初の結果を返すと、クライアント側のバグが隠蔽されてしまいます。パラメータのフィンガープリントを保存し、競合を返してください。

ゲートウェイキャッシュのみで実装する

ゲートウェイによるキャッシングは、ビジネストランザクションから切り離されてしまう可能性があります。重複排除レコードには、信頼性の高い整合性またはリカバリ可能な補償処理が必要です。

フォローアップ質問

なぜすべてのPOSTをサポートしないのか?

副作用とコストが異なるためです。価値の低いエンドポイントに複雑なコントラクトを課すのではなく、まずは高リスクなシナリオをカバーします。

最初のリクエストがまだ実行中の場合はどうするか?

ポーリングまたはサブスクリプション用の明示的な進行中ステータスと操作IDを返し、2つ目の副作用を並行して実行しないようにします。

リージョン間でキーの一貫性をどのように保つか?

単一のプライマリリージョンまたはテナント単位のシャーディングから開始します。マルチリージョンのサポートには、キャッシュのレプリケーションだけでなく、整合性のある重複排除ストレージと障害訓練が必要です。

失敗したレスポンスは再利用できるか?

コントラクトでは、リトライ可能な一時的障害と恒久的な障害を区別し、ステータスとボディがキャッシュされるかどうかを明記する必要があります。Stripeは最初のリクエストの結果を保存するため、顧客はTTLとエラーセマンティクスを理解しておく必要があります。

公開情報ソース

関連する質問