アーキテクチャ
アーキテクチャグラフの代わりにコンポーネントを使用する

グラフの代わりにコンポーネントを使用する

Gato GraphQLはデータモデルを表現するためにグラフを使用しません。代わりに、コンポーネントを使用します。

これは予想外のアプローチではありません。GraphQLプロジェクトはThinking in Graphsというタイトルのもとで、次のように述べています(強調は引用者):

グラフは、私たちの自然な思考モデルや基礎となるプロセスの言語的な説明に似ているため、多くの現実世界の現象をモデル化するための強力なツールです。GraphQLでは、スキーマを定義することでビジネスドメインをグラフとしてモデル化します。スキーマ内では、さまざまなノードの型と、それらがどのように接続・関連するかを定義します。クライアント側では、これはオブジェクト指向プログラミングに似たパターンを生み出します:他の型を参照する型です。サーバー側では、GraphQLはインターフェースのみを定義するため、あらゆるバックエンド(新規または既存!)で自由に使用できます

この定義から得られる重要な点は次のとおりです:

レスポンスがグラフの形を持っているとしても、それはサーバー側でデータを処理する際にデータが実際にグラフとして表現されていることを意味するわけではありません。グラフはあくまで_メンタルモデル_であり、実際の実装ではありません

これは良いニュースです。なぜなら、グラフ(またはツリー)を扱うことは容易ではないからです。一方、コンポーネントははるかに実装が簡単で、同じメリットをすべて提供します。

コンポーネントによるデータモデルの簡素化

サーバー側でデータ構造を表現するためにコンポーネントを使用することは、シンプルさの観点から最適です。なぜなら、データのさまざまなモデルを単一の構造に統合できるからです。次のようなフローの代わりに:

コンポーネントに供給するクエリを構築(クライアント) => データをグラフ/ツリーとして処理(サーバー) => コンポーネントにデータを供給(クライアント)

...フローは次のようになります:

コンポーネント(クライアント) => コンポーネント(サーバー) => コンポーネント(クライアント)

これが実現可能なのは、GraphQLリクエストが「コンポーネント階層」のデータ構造を持つと考えられるためです。各オブジェクト型がコンポーネントを表し、あるオブジェクト型から別のオブジェクト型へのすべてのリレーションシップフィールドが、別のコンポーネントをラップするコンポーネントを表します。

コンポーネントとGraphQLクエリの関係を視覚化するために例を使ってみましょう。次のような「注目の監督」ウィジェットを作成したいとします:

注目の監督ウィジェット

VueやReact(またはその他のコンポーネントベースのライブラリ)を使用する場合、まずコンポーネントを特定します。この場合、外側のコンポーネント<FeaturedDirector>(赤)があり、それがコンポーネント<Film>(青)をラップし、さらにそれがコンポーネント<Actor>(緑)をラップします:

ウィジェット内のコンポーネントの識別

擬似コードは次のようになります:

<!-- Component: <FeaturedDirector> -->
<div>
  Country: {country}
  {foreach films as film}
    <Film film={film} />
  {/foreach}
</div>
 
<!-- Component: <Film> -->
<div>
  Title: {title}
  Pic: {thumbnail}
  {foreach actors as actor}
    <Actor actor={actor} />
  {/foreach}
</div>
 
<!-- Component: <Actor> -->
<div>
  Name: {name}
  Photo: {avatar}
</div>

次に、各コンポーネントに必要なデータを特定します。<FeaturedDirector>にはnameavatarcountryが必要です。<Film>にはthumbnailtitleが必要です。そして<Actor>にはnameavatarが必要です:

各コンポーネントのデータプロパティの識別

そして、必要なデータを取得するGraphQLクエリを構築します:

query {
  featuredDirector {
    name
    country
    avatar
    films {
      title
      thumbnail
      actors {
        name
        avatar
      }
    }
  }
}

ご覧のとおり、上記のコンポーネント階層とこのGraphQLクエリの間には直接的な関係があります。