为接口编写 Apollo 解析器

Posted

技术标签:

【中文标题】为接口编写 Apollo 解析器【英文标题】:Writing an Apollo resolver for an interface 【发布时间】:2018-11-03 02:58:18 【问题描述】:

假设我有以下 typedef:

interface Node 
  id: ID!


type Foo implements Node 
  id: ID!
  quantity: Int


type Bar implements Node 
  id: ID!
  name: String

我发送的每个 ID,我都想以同样的方式处理。目前我需要一些解析器,例如:


  // ...
  Foo: 
    id: (root) => encodeId(root.id, root.type),
    // ...
  ,
  Bar: 
    id: (root) => encodeId(root.id, root.type),
    // ...
  ,
  // ...

由于许多类型实现了Node,这会导致大量代码重复,并且开发人员很容易忘记编码 id 的正确方法,或者忘记将它们一起编码。

有没有办法做这样的事情?


  // ...
  Node: 
    __resolveType: (root) => root.type,
    id: (root) => encodeId(root.id, root.type)
  ,
  // ...

这样FooBarNode 的任何其他实现将继承id 解析器?

【问题讨论】:

【参考方案1】:

对于仍然对这个问题感到困惑的人,您可以将makeExecutableSchema 中的inheritResolversFromInterfaces 标志设置为true

在这里找到它:https://github.com/apollographql/graphql-tools/issues/762#issuecomment-385591309

Apollo 文档在这里:https://www.apollographql.com/docs/apollo-server/api/apollo-server/#makeexecutableschema

【讨论】:

【参考方案2】:

这是一个有趣的问题。我不确定接口的解析器是否会接受__resolveType 以外的任何内容。

我偶尔会遇到这样的问题,但我使用默认和组合解析器修复它。

例如,对于 Node,您可以使用以下默认解析器:

const defaultNodeIdResolver = (root) => encodeId(root.id, root.type)
const defaultNodeOtherFieldResolver = (root) => root /* do something */

const defaultNodeResolvers = 
  id: defaultNodeIdResolver,
  otherField: defaultNodeOtherFieldResolver,

那么你可以按如下方式实现另一个:


  // ...
  Foo: 
    // use object spread
    ...defaultNodeResolvers,
    // ...
  ,
  Bar: 
    // pick a specific resolver
    id: defaultNodeIdResolver,
    // ...
  ,
  Baz: 
    ...defaultNodeResolvers,
    // you can even "override"
    id: (root) => root,
  ,

这也有助于将解析器逻辑与解析器定义分离。我建议随着项目的发展。您还可以在解析器组合中工作(请参阅https://www.apollographql.com/docs/graphql-tools/resolvers.html#graphql-resolvers)。

您只需要确保您可以访问对象传播。无论如何你应该。很有帮助。

【讨论】:

是的,这或多或少是我最终的结果。对于我的每个interfaces,我都有一个implementsXYZ 对象,其中包含我想要共享的解析器,并在实现它的每种类型上使用扩展运算符。

以上是关于为接口编写 Apollo 解析器的主要内容,如果未能解决你的问题,请参考以下文章

无法理解 apollo-client 中解析器的使用

TypeORM Apollo 嵌套查询解析器

如何使用 apollo / graphql 实现节点查询解析器

Apollo GraphQL - 未触发解析器

合并 Apollo 服务器的 GraphQL 解析器不使用 Object.assign()

上下文未传递给嵌套的 Apollo GraphQL 解析器