Relay 和 GraphQL 接口是啥以及如何工作?

Posted

技术标签:

【中文标题】Relay 和 GraphQL 接口是啥以及如何工作?【英文标题】:What and How does Relay and GraphQL interfaces work?Relay 和 GraphQL 接口是什么以及如何工作? 【发布时间】:2017-08-12 03:55:10 【问题描述】:

我们在 GraphQL 中这样定义一个类型:

  const GraphQLTodo = new GraphQLObjectType(
  name: 'Todo',
  fields: 
    id: globalIdField('Todo'),
    text: 
      type: GraphQLString,
      resolve: (obj) => obj.text,
    ,
    complete: 
      type: GraphQLBoolean,
      resolve: (obj) => obj.complete,
    ,
  ,
  interfaces: [nodeInterface], // what is this?
);

我读过 GraphQLInterfaceType - 当类型基本相同但某些字段不同时更合适(这类似于外键吗?)

在 Relay 中,我们通过 nodeDefinitions 获得 nodefield 和 nodeInterface:

const nodeInterface, nodeField = nodeDefinitions(
  (globalId) => 
    const type, id = fromGlobalId(globalId); 
    if (type === 'Todo') 
      return getTodo(id);
     else if (type === 'User') 
      return getUser(id);
    
    return null;
  ,
  (obj) => 
    if (obj instanceof Todo) 
      return GraphQLTodo;
     else if (obj instanceof User) 
      return GraphQLUser;
    
    return null;
  
);

文档和示例只在接口上使用了一个:[] //它是一个数组。但是什么时候需要使用很多接口呢?我只是对它是什么感到困惑,我已经阅读了很多关于它的内容(不知道我的理解是否正确),只是似乎无法将它包裹在我的脑海中

【问题讨论】:

【参考方案1】:

GraphQLInterfaceType 是 GraphQL 实现多态性的一种方式,即由多个对象类型组成的类型。例如,假设您有两种基本对象类型,PostComment。假设您想要一个可以获取cmets 和帖子 列表的字段。方便的是,这两种类型都有idtextauthor 字段。这是接口类型的完美用例。接口类型是一组共享字段,它可以由拥有这些字段的任何对象类型实现。所以我们创建了一个Authored 接口并说CommentPost 实现了这个接口。通过将此 Authored 类型放在 GraphQL 字段上,该字段可以解析帖子或 cmets(或这两种类型的异构列表)。

但是等等,PostComment 接受一个接口数组。我可以在这里传递多个接口。为什么?由于实现接口的要求是拥有该接口中的所有字段,所以没有理由任何对象类型不能实现多个接口。借鉴您的示例,Relay 中的Node 接口只需要id。由于我们的PostCommentid,它们可以实现both NodeAuthored。但许多其他类型可能会实现Node,它们不属于Authored

这使您的对象类型更加可重用。如果您将接口分配给您的字段而不是对象类型,那么您可以轻松地将新的可能类型添加到架构中的字段,只要您坚持这些约定的接口。

【讨论】:

以上是关于Relay 和 GraphQL 接口是啥以及如何工作?的主要内容,如果未能解决你的问题,请参考以下文章

Relay 和 GraphQL 中的身份验证

如何使用 Relay 容器、react-router 和 GraphQL 按 id 获取和显示项目

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

Relay / GraphQL 'resolve' 是如何工作的?

在graphql中实现多个接口

GraphQL、Relay 和 Mongodb (mongoose) 如何获取数组