在中继中,节点接口和全局ID规范起什么作用? [英] In Relay, what role do the node interface and the global ID spec play?

查看:80
本文介绍了在中继中,节点接口和全局ID规范起什么作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从relay-starter-kit开始,还通过Relay和GraphQL文档进行工作.但是,有很多地方是无法解释和神秘的.

I started out with the relay-starter-kit and also worked my way through the Relay and GraphQL documentation. But there are quite a few areas that are unexplained and mysterious.

我认真地阅读了很多关于所有这些事情的文档,但是找不到以下问题的令人满意的解释:

Seriously I read a lot of documentations everywhere about all these things but couldn't find any satisfying explanations for the following questions:

这是做什么用的?我放置了日志记录,但它甚至根本没有被调用:

What is this for? I put logging but it never even gets called at all:

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字段的作用是什么

Maybe related to that, what does the node field here do:

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

id字段的神奇之处是什么? globalIdField是做什么用的?

And what is the magic around the id field? What is globalIdField for?

我的数据库中有一个id,并认为我可以在我的GraphQL对象中使用它:

I have an id in my database and thought I could use it in my GraphQL objects:

代替:

id: globalIdField('User'),

我要使用我的数据库ID:

I want to use my database id:

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

但是,如果我这样做,我会在浏览器中看到一个错误,提示RelayQueryWriter: Could not find a type name for record '1'.

But if I do that I get an error in the browser saying RelayQueryWriter: Could not find a type name for record '1'.

我可以通过在组件容器的中继查询"中添加__typename来消除该错误,但这似乎是错误的.

I can get rid of that error by adding __typename to my component containers Relay Query but that seems all wrong.

如果您能在此提供更深入的了解和更好的解释并增强官方文档,那就太好了.

It would be great if you could give some deeper insides and a better explanation here and enhance the official documentation.

谢谢

推荐答案

当Relay需要 refetch 一个对象时,Node根字段与全局唯一ID一起起作用.当您调用this.props.relay.forceFetch()或将查询的字段添加到由于全局ID已被部分提取而已知全局ID的对象时,就会发生重新引用.

The Node root field, in combination with globally unique IDs, comes into play when Relay needs to refetch an object. Refetching occurs when you call this.props.relay.forceFetch() or when you add fields to the query for an object whose global ID is known because it has already been partially fetched.

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

In cases like these, Relay will short circuit the regular query and execute a query for the object(s) directly using its global ID and the node root call.

示例:

假定第一次解决此查询时$showCommentsfalse.

Assume that $showComments was false when this query was first resolved.

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

这将导致某些故事的idtext的获取,这些故事的ID现在已知.

This will have caused a fetch for id and text for some number of stories, whose IDs are now known.

想象在将来的某个时间,变量$showComments变为true.中继将使用node根字段仅重新获取所需的数据.

Imagine that at some future time, the variable $showComments became true. Relay will refetch only the data it needs using the node root field.

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.
  1. Each object must have a globally unique ID, or be identified by a type/ID pair (the globalIdField helper does this and produces a base64 encoded string).
  2. The server must know how to resolve an object from a globally unique ID, and vice versa. This is what the nodeDefinitions are for.
  3. Any object that hopes to be refetchable using this system must implement the nodeInterface.

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

这篇关于在中继中,节点接口和全局ID规范起什么作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆