2015-10-28 36 views
43

我从relay-starter-kit开始,也是通过Relay和GraphQL文档工作的。但是有不少地方是无法解释和神秘的。在Relay中,节点接口和全局标识规范起什么作用?

认真我读了很多单证的处处讲这些东西,但无法找到以下问题的任何令人满意的解释:

是什么呢?我把记录,但它从来没有得到调用:

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添加到我的组件容器中继查询中来摆脱该错误,但这似乎都是错误的。

如果你能在这里给出更深入的内涵和更好的解释并且增强官方文档,这将是非常棒的。

谢谢

回答

51

Node根场,结合全球唯一的ID,进场时,继电器需要重取的对象。当您调用this.props.relay.forceFetch()时,或者当您向查询中添加字段时发生重新访问,因为对象的全局ID已知,因为它已被部分提取。

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

假设$showCommentsfalse当该查询首先被解决。

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

这将造成对idtext一个取一些数字的故事,他的ID是目前已知的。

试想一下,在未来某个时间,变量$showComments成为true。中继将仅使用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是refetchable任何对象。

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

+2

希望这将使其进入教程很快。我也被这个困惑了很长一段时间,直到我终于完成了所有工作,并将这些部分拼凑在一起。 –

+3

也许在'fromGlobalId'和'toGlobalId'这个答案中多加点儿?以及它们如何便利重新绘制任何对象类型?读取https://github.com/graphql/graphql-relay-js/blob/master/src/node/node.js和该回购协议中的其他文件对我有很大帮助,但将这些东西转化为文字可以为我节省大量的时间。 –

+0

对于一个简洁的(你可以跳到结尾的总结)的代码说明解释什么神秘nodeInterface,nodeField,globalFieldId是,也许https://medium.com/p/relay-graphql-de-mystifying- node-id-38757121b9c – nethsix

相关问题