使用 Relay 和 GraphQL 进行查询

Posted

技术标签:

【中文标题】使用 Relay 和 GraphQL 进行查询【英文标题】:Query with Relay and GraphQL 【发布时间】:2015-11-27 01:11:23 【问题描述】:

我正在关注 React + Relay + GraphQL @https://facebook.github.io/relay/docs/tutorial.html 的教程

我对什么 interface : [nodeInterface] 在 GraphQL 对象定义中的作用感到困惑。

【问题讨论】:

【参考方案1】:

对于符合 Relay 的 GraphQL 服务器,具有全局 ID 的对象称为 Node,任何 node 都可以通过查询重新获取


  node: (id: "some global id") 
    id,
    ... on SomeType 
      someField
    
  
 

Node 接口用于 GraphGL 模式,它可以帮助您定义具有全局 id 的类型。

查看Global Object Identification的详细信息,它是Specification

【讨论】:

【参考方案2】:

简答

nodeInterface 仅在客户端(通常是浏览器)请求一段 GraphQL 数据时才使用,该数据从初始获取中已经拥有,要重新获取。

在以下任何一种情况下都会执行重新提取:

不同/相同的 React 组件(在同一网页上)在稍后阶段请求额外的数据片段,而这些数据在获取的初始数据中不可用 React 组件中的代码执行this.props.relay.forceFetch(),这通常发生在程序员认为服务器端的数据可能由于其他外部原因而发生变化时 React 组件中的代码执行this.props.relay.setVariable(...),当用户执行需要更改初始获取数据的操作(例如更改要显示的项目数量、图片大小等)时。

在重新获取期间,GraphQL 使用(全局)节点 ID 调用 nodeInterfacenodeInterface 需要检索与该节点 ID 关联的服务器端对象。使用该服务器端对象,GraphQL 服务器可以返回客户端所需的附加/变化数据。

因此,如果从不重新感染初始对象数据,则永远不需要节点 ID。

更多详情请参考:https://medium.com/@khor/relay-graphql-de-mystifying-node-id-38757121b9c

详情

nodeInterface 执行节点 ID 到服务器端对象解析,因此它总是看起来像:

var nodeInterface, nodeField = nodeDefinitions(
  (globalId) => 
    var type, id = fromGlobalId(globalId);

    if (type === 'ClassA') 
      // Get ClassA type of instance with id
      // E.g.,
      return ClassA.find_by_id(id)
     else if (type === 'ClassB') 
      return ClassB.find_by_id(id)
    

    ...
  
)

由于需要重新获取的 GraphQL 类型需要节点 ID,因此在 GraphQL 架构中您需要:

请求 GraphQL 在创建 GraphQL 类型的实例时使用 globalIdField 关键字自动生成节点 ID 告诉 GraphQL GraphQL 类型如何将重新获取期间提供的节点 ID 解析回相应的服务器端对象,即您的 interface : [nodeInterface]

因此:

var ClassAType = new GraphQLObjectType(
  name: 'ClassA',
  description: 'A',
  fields: () => (
    id: globalIdField('ClassA'),

    ... other fields ...

  ),
  interfaces: [nodeInterface],
);

【讨论】:

以上是关于使用 Relay 和 GraphQL 进行查询的主要内容,如果未能解决你的问题,请参考以下文章

GraphQL/Relay Schema 无法在“CreateLinkPayload”类型上查询字段“store”

如何在 GraphQL (Relay) 中查询和改变数组类型?

使用 Django GraphQL JWT 和 Graphene Relay 进行身份验证和授权

GraphQL 和 Relay 中的模式之间的区别

GraphQL / Relay - 是不是需要在主 QueryRenderer 中查询所有表?

如何使用 GraphQL 联合实现 Relay 节点查询