プロンプトとコンテキスト
あなたは成熟したREST APIを持つB2B SaaSを担当しています。大口顧客は複数リソースにまたがるクエリを結合するためにGraphQLを求めていますが、エンジニアリング組織はクエリコスト、認可境界、キャッシュ、長期的なガバナンスを懸念しています。GraphQLを導入すべきかどうかを判断し、スコープ、メトリクス、リスク、移行計画を説明してください。
これはAPIのプロダクト判断であり、GraphQLサーバーの実装を問うものではありません。GraphQLの仕様は、データモデルの機能と要件に対するクエリ言語および実行エンジンを定義しています。GitHubのパブリックAPIはクエリとミューテーション(mutations)の両方をサポートしています。あなたの役割は、それらの機能を検証可能なプロダクトの選択肢へと落とし込むことです。
面接官がテストしているポイント
- 単にGraphQLが流行しているからという理由ではなく、顧客のワークフローと測定可能な課題から出発しているか。
- ディスカバリ、ラウンドトリップ、認可、キャッシュ、オブザーバビリティの観点で、REST、GraphQL、および集約層(Aggregation Layer)を比較できているか。
- スキーマ、クエリの複雑性、ページネーション、ミューテーションの境界をプロダクトの制約として落とし込めているか。
- 段階的なパイロット、互換性計画、価格設定アプローチ、開発者体験(Developer Experience)メトリクスを設計できるか。
最初に行うべき確認事項
- 課題はラウンドトリップの削減、オーバーフェッチの低減、あるいは複数リソースの結合(クロスリソースコンポジション)のどれですか? 既存のREST集約エンドポイントで解決可能ですか?
- スコープにはいくつのコンシューマー、言語スタック、コンプライアンス地域、目標SLOが含まれますか? パートナーは安定したAPIコントラクトに依存していますか?
- 読み取り専用のクエリで十分ですか、それとも書き込みも必要ですか? 書き込みにはトランザクション、冪等性、承認フローが必要ですか?
- どのリソースとフィールドがテナント境界を定義しますか? 深さ(depth)、レスポンスサイズ、テナントごとのバジェットはどのように制限しますか?
30秒での回答
私なら、顧客との間で繰り返し発生しているデータ結合の課題を検証し、まずは小さな読み取り専用リソースセットでパイロット運用を行います。RESTの集約エンドポイントによって高価値なワークフローが低コストで解決できるなら、プロトコルのためだけにGraphQLを導入することはしません。複数の顧客が異なるフィールドの組み合わせを必要としており、個別のカスタムエンドポイントを維持するコストが高い場合は、制約を設けたGraphQLプロダクトを導入します。最初のリリースでは、安定したクエリスキーマ、ページネーション、複雑性バジェットを公開し、既存のID管理およびテナント認可を再利用し、任意のミューテーションの提供は見送ります。アクティベーション率、成功率、P95レイテンシ、クエリコスト、サポート負荷、RESTからの移行状況に基づいて、拡大するか中止するかを判断します。
ステップごとの詳細解説
顧客価値と代替案を先に定義する
リクエスト内容を、ネットワークラウンドトリップの削減、オーバーフェッチの低減、クロスリソース結合に分解します。それぞれについて、現在のRESTコールグラフ、エンドツーエンドのレイテンシ、個別エンドポイントの数、顧客側で構築されたプロキシのコストを記録します。1つのREST集約エンドポイントで最も価値の高いワークフローの大半が解決できるなら、単にリクエスト数を数えるだけでなく、GraphQLのガバナンスコストも比較に含めます。
データベースを直接公開するのではなくプロダクト境界を設定する
最初のスキーマは、安定したセマンティクス、明確なテナント所有権、観測可能な挙動を持つリソースを対象とすべきです。すべてのフィールドに機密性、認可ルール、バージョニングの保証、鮮度(freshness)をタグ付けします。クエリとミューテーションは分けて検討します。まず読み取りの価値を検証し、冪等性、監査、エラーセマンティクスが成熟した後に書き込みを検討します。
クエリコストを強制可能なバジェットにする
GraphQLの柔軟な選択セット(selection set)は、コストの発生要因をエンドポイント数からクエリの形状へと変化させます。最大深度、ノード数、ページサイズ、タイムアウトを制限し、スキーマフィールドまたはリゾルバー(resolver)単位でコストを見積もります。バジェット超過のリクエストは具体的なエラーを返して拒絶しつつ、テナント、オペレーション名、推定コスト、実際のリソース使用量を記録します。
アイデンティティ、認可、テナント境界を維持する
GraphQLはリクエストの形状を変えるだけであり、既存のOAuth、サービスアカウント、テナント分離、フィールドレベルの権限をバイパスしてはなりません。ルートクエリだけでなく、リゾルバーまたは共有データアクセス層で認可を強制します。バッチ読み取りでは、クロステナントの結合、不正なキャッシュの再利用、エラーを通じた情報漏洩を防止する必要があります。
開発者体験と互換性を計画する
スキーマドキュメント、サンプルクエリ、エラーハンドリングのガイダンス、ページネーションの規約、オペレーション名の必須化、変更ログ(changelog)を提供します。破壊的なスキーマ変更には、非推奨期間(deprecation window)、呼び出し元のスキャン、担当窓口の設定が必要です。RESTとGraphQLはドメインモデルを共有できますが、永続的に1対1のフィールド完全一致を保証してはなりません。
パイロット、メトリクス、終了基準を定義する
2〜3社の代表的な顧客を選び、固定のリソースとバジェットを定めて読み取り専用のワークフローを対象とします。アクティブなアプリ数、有効なクエリ率、P95/P99レイテンシ、クエリごとのコスト、ブロックされた認可試行回数、サポートチケット数、顧客のタスク完了時間を追跡します。利用率の低迷、高コスト、ガバナンスインシデントの増加が見られた場合は、フィールドを追加して問題を覆い隠すのではなく、スキーマを縮小するか拡張を停止すべきです。
{
"pilot": {"tenants": 3, "mode": "read-only", "maxDepth": 6, "costBudget": 100},
"exit": {"p95LatencyMs": 400, "errorRate": 0.01, "supportTicketsPerTenant": 2}
}優れた回答例
私はGraphQLをRESTの不可避な置き換えとは見なしません。顧客の根拠に基づいて、結合、オーバーフェッチ、または個別エンドポイントの保守負担が十分に大きいかを確認し、REST集約層の提供コストと比較します。パイロットによってその価値が証明された場合、適切に統制されたAPIプロダクトとしてGraphQLを製品化します。具体的には、安定した読み取り専用スキーマ、既存のOAuthとテナント認可、必須のオペレーション名、深さ・ノード・ページネーション・コストの制限、さらにスキーマドキュメントと非推奨期間を設けます。Google ApigeeはAPIプロダクトをリソース、メソッド、アクセスレベル、クォータのバンドルとしてモデル化していますが、これはGraphQLのアクセス制御、制限、プランを包括的に設計する上で有用な指針です。アクティブ顧客数、成功率、P95、ユニットクエリコスト、サポート負荷を用いて拡張の是非を判断し、その段階になって初めてリソースの追加やスコープを限定したミューテーションの提供を行います。
よくある間違い
- 顧客価値を証明したりREST集約と比較したりすることなく、「フロントエンドの柔軟性が高まる」とだけ主張する。
- GraphQLスキーマをデータベーステーブルに直接マッピングし、ドメインセマンティクス、認可、機密フィールドを無視する。
- コストモデルや拒否戦略を持たずに、無制限の深度、ページネーション、ネストを許可する。
- 冪等性、監査、承認、ロールバックの境界を定めずに、クエリとミューテーションを同時にローンチする。
- レイテンシ、コスト、ブロックされた認可、サポート負荷を無視し、導入率だけを追跡する。
- デュアルトラックのドキュメント、非推奨化、ロールバックを無視して、すべてのREST顧客に対して1回限りの移行を約束する。
フォローアップ質問と回答
顧客がリクエスト数の削減だけを求めている場合、なぜREST集約を作成しないのですか?
コールグラフと保守コストを用いて両方の選択肢を定量化します。境界が明確で頻度が高い固定のワークフローであれば集約エンドポイントが有利です。多数の顧客にわたって組み合わせが絶えず変化する場合は、制約付きのGraphQLの方が価値が高くなります。プロトコル表面を選択する前に、同じワークフローでパイロットを実施します。
GraphQLクエリによってバックエンドがダウンするのをどのように防ぎますか?
エッジで深さ、ノード、ページネーション、タイムアウトの制限を強制し、スキーマ内でフィールドコストの重み付けを管理し、リゾルバーでバッチ処理とキャッシュを行い、テナントおよび優先度ごとにレート制限を適用します。拒絶されたクエリに対しては、不透明なサーバーエラーを返すのではなく、オペレーション名、推定コスト、リソース使用量をログに記録します。
ミューテーションはいつ公開しますか?
読み取り専用の認可、エラー処理、監査、オブザーバビリティが安定した後に限られます。リスクが低く、冪等性があり、補償可能な書き込みから開始します。各ミューテーションには、入力バリデーション、競合セマンティクス、パーミッション、監査イベント、リトライ挙動が必要です。財務処理、削除処理、クロステナントのアクションは、専用のワークフローとして維持すべきです。
RESTとGraphQLはどのように共存させますか?
RESTを安定した互換性維持のためのインターフェースとして維持し、GraphQLはフィールド単位の完全一致を求めずに新しいワークフローに利用します。アイデンティティ、ドメイン認可、監査、SLOを共有しつつ、呼び出し元の移行状況と各インターフェースのコストを個別に測定します。RESTの非推奨化は、顧客価値、運用コスト、互換性リスクが確固たる根拠によって裏付けられた場合にのみ検討します。