アーキテクチャ
アーキテクチャCode-firstのGraphQLサーバー

Code-firstのGraphQLサーバー

GraphQLスキーマは、サービスに対して実行できる型・フィールド・ミューテーションのセットを公開することで、GraphQLサービスの契約を定義します。GraphQLサービスを作成する際、次のいずれかを選択できます。

  • スキーマを唯一の信頼できる情報源とし、実装コード全体がその定義に従う
  • コードを唯一の信頼できる情報源とし、スキーマはコードから生成されるアーティファクトとする

どちらの場合も完全に機能するGraphQLサービスが得られますが、選択するアプローチによって、将来的に実現できる機能の多寡や実装の容易さが変わってきます。この二つのアプローチはそれぞれ「schema-first」(より正確には「SDL-first」)と「code-first」と呼ばれています。

Gato GraphQLはcode-firstアプローチを採用しています。その理由を見ていきましょう。

Gato GraphQLがcode-firstを採用する理由

code-firstアプローチでは、まずリゾルバーをコーディングし、そのコードを唯一の情報源としてスキーマをアーティファクトとして生成します。つまり、スキーマはスクリプトを実行することで作成され、SDL-firstのように手動で作成されるわけではありません。code-firstにもスキーマが存在するため、SDL-firstが提供する重要な機能は何も失われません。

しかしながら、code-firstはSDL-firstに対して重要な機能を一つ追加で提供します。それが「動的スキーマ」の提供です。動的スキーマはコンテキストに応じて形状や属性を変化させることができ、実行時にコードで制御されます。実際、Gato GraphQLが提供するすべての優れた機能は、code-firstの採用がもたらした直接的な成果です。

code-firstの利点

動的スキーマは、以下をはじめとする数多くの利点を提供します。

スキーマの信頼できる情報源は、GraphQLが要求するものの上位集合です。追加のプロパティ(グローバルフィールド、グローバル接続、グローバルディレクティブ、永続化されたフラグメントなど)は、GraphQL仕様に追加されるのを待つことなく、すでにAPIで利用できます(仕様への追加が実現するかどうかにかかわらず)。

信頼できる情報源がスキーマに縛られていないため、他のシステム向けにも任意のスキーマを生成できます。GraphQLはターゲットの一つに過ぎません。たとえば、同じ情報源からRESTサービス向けのJSON-schemaを生成することも可能です。

APIはユーザーのログイン状態やログイン済みユーザーのロールに応じて、同時にパブリック・プライベートの両方の性格を持つことができ、PRO会員への支払い有無といったその他のプロパティに基づいて提供するフィールドの多寡を変えることもできます。

型は事前にどのフィールドを解決するかを知りません。代わりに、フィールドリゾルバーはpublish-subscribeパターンを使って型リゾルバーに自身を関連付け、フィールドリゾルバーが他のフィールドリゾルバーをオーバーライドできます。この機能によりAPIは非常に拡張しやすくなり、APIの汎用コードを用意しながら、特定のクライアントやプロジェクトに合わせてアプリケーションレベルでカスタマイズすることが可能になります。

一つのフィールドは単一のフィールドリゾルバーだけでなく、複数のフィールドリゾルバーによって処理されることがあります。チェーン内の各フィールドリゾルバーは、実行時に何らかのプロパティに基づいてフィールドを処理するかどうかを判断し、処理しない場合はチェーンに渡すことができます。たとえば、フィールド引数 "source: testing" が渡された場合にのみ使用される特殊なフィールドリゾルバーを設けることで、一般公開前に本番環境の一部サイトでテストできます。同じ戦略により、他の場所への意図しない副作用を生じさせることなく、特定のクライアントや環境向けに迅速なバグ修正を提供することも可能です。

型とインターフェースは、サードパーティとの衝突を避けるために自動的に名前空間が付与されます。