web-dev-qa-db-ja.com

リレーで、ノードインターフェイスとグローバルID仕様はどのような役割を果たしますか?

私はrelay-starter-kitから始めて、RelayとGraphQLのドキュメントの作成も行いました。しかし、説明されておらず、神秘的な領域がかなりあります。

真剣に私はこれらすべてについてどこでもたくさんのドキュメントを読みましたが、次の質問について満足のいく説明は見つかりませんでした:

これは何のため?ログを記録しましたが、まったく呼び出されません。

var {nodeInterface, nodeField} = nodeDefinitions(
  (globalId) => {
    var {type, id} = fromGlobalId(globalId);
    if (type === 'User') {
      return getUser(id);
    } else if (type === 'Widget') {
      return getWidget(id);
    } else {
      return null;
    }
  },
  (obj) => {
    if (obj instanceof User) {
      return userType;
    } else if (obj instanceof Widget) {
      return widgetType;
    } else {
      return null;
    }
  }
);

そして、これの実際の効果は何ですか:

interfaces: [nodeInterface],

おそらくそれに関連して、ここのnodeフィールドは何をしますか:

var queryType = new GraphQLObjectType({
  name: 'Query',
  fields: () => ({
    node: nodeField,
    // Add your own root fields here
    viewer: {
      type: userType,
      resolve: () => getViewer(),
    },
  }),
});

そして、idフィールドの周りの魔法は何ですか? globalIdFieldの目的は何ですか?

データベースにidがあり、それをGraphQLオブジェクトで使用できると思いました。

の代わりに:

id: globalIdField('User'),

データベースIDを使用したい:

id: {
  type: GraphQLID,
  description: 'The identifier'
},

しかし、そのようにすると、ブラウザにRelayQueryWriter: Could not find a type name for record '1'と言うエラーが表示されます。

コンポーネントコンテナーのリレークエリに__typenameを追加することでそのエラーを取り除くことができますが、それはすべて間違っているようです。

ここでより深い内部とより良い説明を提供し、公式ドキュメントを強化できれば素晴らしいと思います。

ありがとうございました

52
Christine

Nodeルートフィールドは、グローバルに一意のIDと組み合わせて、Relayがオブジェクトをrefetchする必要があるときに機能します。再フェッチは、this.props.relay.forceFetch()を呼び出したとき、またはすでに部分的にフェッチされているためにグローバルIDがわかっているオブジェクトのクエリにフィールドを追加したときに発生します。

このような場合、Relayは通常のクエリを短絡し、グローバルIDとnode root呼び出しを使用してオブジェクトのクエリを直接実行します。

と仮定する $showCommentsは、このクエリが最初に解決されたときはfalseでした。

query {
  viewer {
    stories(first: 10) {
      edges {
        node {
          id,
          comments(first: 10) @include(if: $showComments) { 
            author, 
            commentText 
          }
          text,
        }
      }
    }
  }
}

これにより、いくつかのストーリーのidtextのフェッチが発生しますが、そのIDは現在既知です。

将来のある時点で、変数$showCommentstrueになりました。リレーは、nodeルートフィールドを使用して、必要なデータのみを再フェッチします。

query {
  node(id: "ABC123") { 
    fragment on Story { comments(first: 10) { author, commentText } }
  }
  node(id: "DEF456") { 
    fragment on Story { comments(first: 10) { author, commentText } }
  }
  node(id: "GHI789") { 
    fragment on Story { comments(first: 10) { author, commentText } }
  }
  ...
}

これはいくつかの要素に依存します:

  1. 各オブジェクトはグローバルに一意のIDを持っているか、タイプ/ IDペアで識別される必要があります(globalIdFieldヘルパーがこれを行い、base64エンコードされた文字列を生成します)。
  2. サーバーは、グローバルに一意のIDからオブジェクトを解決する方法、およびその逆の方法を知っている必要があります。これがnodeDefinitionsの目的です。
  3. このシステムを使用して再フェッチを希望するオブジェクトは、nodeInterfaceを実装する必要があります。

参照: https://facebook.github.io/relay/docs/graphql-object-identification.html#content

54
steveluscher