代表的な面接トピック

システムデザイン面接:LWSを用いたパーミッション付き外部ストレージをどのように設計するか?

システム設計難しい
Offer.cc 編集チーム公開日 更新日

質問

複数のアプリケーション向けに相互運用可能な外部データストレージサービスを設計してください。クライアントはストレージの検出、読み取り/書き込みアクセスのリクエスト、リソースの作成、および変更のサブスクライブができる必要があります。リソースモデリング、HTTPセマンティクス、認証、並行性、通知、ロールバックについて説明してください。

プロンプトとスコープ

複数のアプリケーション向けに相互運用可能な外部データストレージサービスを設計してください。クライアントはストレージの検出、読み取り/書き込みアクセスのリクエスト、リソースの作成、および変更のサブスクライブができる必要があります。リソースモデリング、HTTPセマンティクス、認証、並行性、通知、ロールバックについて説明してください。

W3C Linked Web Storage Protocol 1.0は現在ワーキングドラフト(Working Draft)です。アプリケーションに対して、外部に保存されたデータへの安全でパーミッション制御された相互運用可能なアクセスを提供することを目的としています。この仕様では、ストレージおよび親リソースを検出するためにLink関係を使用し、linksetを通じてメタデータを管理し、メタデータの更新とリソース操作の間の原子性を要求します。この質問では、ドラフトを確定した標準として扱うことなく、プロトコルの境界と障害処理をテストします。

面接官が評価するポイント

面接官は、リソース、パーミッション、ID、メタデータ、通知の明確な分離に加え、POSTの再試行、並行PATCH、405/415レスポンス、キャッシュ、失効(revocation)の適切な処理を評価します。優れた回答はワーキングドラフトの不確実性を認識し、デプロイメントのニーズに基づいてOpenID Connect、SAML、自己署名IDスイートの中から適切に選択します。

回答前の明確化のための質問

  • データ所有者、アプリケーション、ストレージサービスはそれぞれ誰が運用しており、信頼境界はどこにありますか?
  • どの操作が必要ですか:読み取り、作成、更新、削除、共有、または読み取り専用サブスクリプションですか?
  • パーミッションはユーザー、エージェント、リソースパス、アクション、それとも時間枠ごとに付与されますか?
  • クロスリージョンアクセス、オフライン利用、監査、失効、結果整合性の通知は必要ですか?
  • クライアントはLinkディスカバリ、ETag、405/415レスポンス、再試行の重複排除を処理できますか?

30秒の回答フレームワーク

「ストレージ、コンテナ、データリソース、linkset、ID、グラント(付与情報)を個別にモデル化します。クライアントはLink関係を介してストレージとその親を検出し、宣言されたスイートで認証を行い、アクション、サブジェクト、ターゲット、制約を含むリクエストを送信します。作成にはPOSTを使用しますが、冪等性キーまたは重複排除によって再試行時の重複を防ぎます。メタデータのPATCHには並行性条件を要求し、リソース操作とアトミックにコミットします。サービスはETag、機能ヘッダー、競合時の構造化エラーを使用し、再試行可能なキューによって結果整合性のある通知を配信します。各カナリアリリースでは失効、古いパーミッションバージョン、監査ロールバックを維持します。」

ステップバイステップの詳細な回答

1. リソースおよびディスカバリモデルの確立

ストレージ、コンテナ、データリソース、linksetを分離します。GETまたはHEADレスポンスは、Link関係を介してストレージルート、親、タイプ、linksetを公開します。クライアントはURL構造をプロトコルの規約として扱ってはなりません。ストレージ記述ではサーバーの機能とメディアタイプを提示し、クライアントがPUTまたは特定のPATCHを送信する前にネゴシエーションできるようにする必要があります。

2. 監査可能なグラントとしてのパーミッションモデリング

グラントには、被付与者、アクション、ターゲット、制約、発行者、有効期間、失効状態を含める必要があります。ストレージサービスは呼び出し元のIDとグラントバージョンを確認し、読み取り、作成、更新、削除について最小権限を適用します。OpenID Connect、SAML、または自己署名IDによって身元を証明できますが、認証とリソースの認可は分離されたままです。ログインの成功があらゆるリソースへのアクセスを意味するわけではありません。

3. 作成、更新、並行性セマンティクスの定義

仕様ではPOSTとサーバー割り当ての最終URIを使用してリソースを作成し、201とLocationを返します。POSTは冪等ではないため、再試行には一意のリクエスト識別子または重複排除レコードが必要です。LinksetのPATCHが主要なメタデータ更新です。更新の喪失を防ぐためにETag、If-Match、または同等のバージョンチェックを使用します。サポートされていないメソッドには405を、サポートされていないメディアタイプには415を返します。

text
POST /alice/notes/ HTTP/2
Idempotency-Key: 7b3c...
Link: <https://www.w3.org/ns/lws#DataResource>; rel="type"
Content-Type: text/plain

meeting notes

4. リソースとメタデータの一貫性維持

作成、コンテナへの所属、および必要なサーバーメタデータはアトミックにコミットされる必要があります。障害によって、親関係やlinksetを持たない可視リソースが残ってはなりません。シャード間では、トランザクションログまたはアウトボックスを使用して状態を記録します。読み取りAPIは、通知の順序からコミットの成功を推測するのではなく、保留中、コミット済み、または失敗の状態を明示的に公開できます。

5. 通知と機能ネゴシエーションの設計

変更イベントを再試行可能なアウトボックスに書き込み、サブスクライバーのインボックスに配信します。ストレージ、リソース、アクション、バージョンを含めます。コンシューマーはイベントIDによって重複排除を行い、GETを使用して現在の状態を検証します。失われた通知はリプレイまたは定期的な調整によって回復し、重複処理は冪等に保ちます。Prefer、Link、メディアタイプネゴシエーションにより、クライアントはすべてのサーバーが単一のPATCHやサブスクリプションモデルをサポートしていると仮定するのではなく、段階的に機能を採用できます。

6. 認証、失効、ロールバックの処理

認証設計にキーローテーション、トークンオーディエンス、クロックスキュー、失効パスを含めます。パーミッションの変更はバージョン管理された監査ログに書き込み、認可チェックとキャッシュ無効化の後に失効を有効にします。まずは低リスクのテナントでカナリアリリースを行い、401/403、405/415、競合率、重複作成、通知レイテンシ、監査の完全性を観察します。権限昇格や孤立データが発生した場合は停止し、古い認可ポリシーを復元します。

高品質な回答例

ストレージ、コンテナ、データリソース、linkset、ID、グラントを分離します。クライアントはGET/HEADのLink関係を介してストレージルート、親、タイプ、linksetを検出し、書き込み前に機能をネゴシエーションします。グラントにはサブジェクト、アクション、ターゲット、制約、有効性、失効が含まれます。OpenID Connect、SAML、または自己署名IDは身元を証明しますが、リソースアクセスを付与するものではありません。POSTは201とLocationを返します。これは冪等ではないため、クライアントは一意のリクエストIDまたは重複排除を使用します。LinksetのPATCHはETag/If-Matchを使用して並行更新の喪失を防ぎ、未サポートのメソッドやメディアタイプには405/415を返します。作成、所属、サーバーメタデータはアトミックにコミットされます。アウトボックスのイベントは再試行可能なインボックスに送信され、コンシューマーはイベントIDで重複排除し、GETで調整します。カナリア展開では401/403、競合、重複、通知レイテンシ、監査の完全性を監視します。権限昇格、孤立リソース、ロールバックの失敗が発生した場合は展開を停止します。プロトコルはワーキングドラフトであるため、最終プロトコルとテストマトリックスはバージョン管理される必要があります。

よくある間違い

  • URLパスをプロトコル規約のすべてとして扱う → ディスカバリと機能ネゴシエーションが壊れる → Link関係、メディアタイプ、機能ヘッダーに依存する。
  • 無条件にPOSTを再試行する → 重複したリソースが作成される可能性がある → 冪等性キー、重複排除レコード、最終状態の読み取りを使用する。
  • ログインのみをチェックし、認可をチェックしない → 身元の証明はターゲットへのアクセスを意味しない → サブジェクト、アクション、ターゲット、制約を評価する。
  • メタデータをリソースとは別にコミットする → 孤立リソースや不正確なlinksetが発生する → アトミックトランザクションまたは回復可能なアウトボックスを使用する。
  • すべてのサーバーがPUT/PATCHをサポートしていると仮定する → クライアントの耐障害性が低下する → 機能を検出し、405/415を適切に処理する。

フォローアップの質問と回答

なぜPOSTの再試行をTCPやHTTPだけに頼ることができないのですか?

サーバーがコミットした後に接続が失敗する可能性があり、クライアントが結果を認識できなくなるためです。一意のリクエストIDとステータスクエリを使用することで、再試行を元のコミットに関連付けます。

パーミッションキャッシュによる失効の遅延をどのように回避しますか?

短いTTLを持つバージョン管理されたグラントを使用し、監査ログの書き込み後に影響を受けるキャッシュを能動的に無効化し、重要な書き込みでは認可バージョンを再確認します。

失われた通知をどのように回復しますか?

アウトボックスにイベントを永続化し、配信を再試行し、コンシューマーのカーソルを保持し、リソースバージョンによって調整し、必要に応じてイベントログをリプレイします。

なぜlinksetの更新はアトミックでなければならないのですか?

リソースの処理は成功しても所属やタイプのメタデータが失敗した場合、ディスカバリ、認可、キャッシュが一貫性のない状態を観測してしまいます。アトミックコミットにより、中途半端に作成されたリソースが外部から見える状態になるのを防ぎます。

ワーキングドラフト期間中の投資をどのように管理・抑制しますか?

分離されたアダプターとバージョン管理されたテストマトリックスを使用し、低リスクのトラフィックのみを試験運用し、古いプロトコルと移行パスを維持し、仕様と実装レポートが安定した後に拡張します。

公開情報ソース

関連する質問

関連面接ツール

システム設計の回答には「回答する」を使用

まず要件を明確にし、スケール、アーキテクチャ、コンポーネント選定、トレードオフの順に進めます。

ツールを見る