52

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'

我可以通过添加到我的组件容器 Relay Query 来消除该错误,__typename但这似乎完全错误。

如果您能在这里提供更深入的内容和更好的解释并增强官方文档,那就太好了。

谢谢

4

1 回答 1

56

当Relay 需要重新获取对象Node时,根字段与全局唯一 ID 结合使用。当您调用或将字段添加到全局 ID 已知的对象时,会发生重新获取,因为它已被部分提取。this.props.relay.forceFetch()

在这种情况下,Relay 将短路常规查询并直接使用其全局 ID 和node根调用执行对象查询。

示例

假设那$showCommentsfalse第一次解决此查询的时间。

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

这将导致一些故事的获取id和获取,这些故事的 ID 现在是已知的。text

想象一下,在未来某个时间,变量$showComments变为true。Relay 将使用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 ://relay.dev/docs/guides/graphql-server-specification/#object-identification

于 2015-10-29T10:15:13.457 回答