【问题标题】:Writing an Apollo resolver for an interface为接口编写 Apollo 解析器
【发布时间】: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 解析器?

【问题讨论】:

    标签: node.js graphql apollo-server apollostack


    【解决方案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 对象,其中包含我想要共享的解析器,并在实现它的每种类型上使用扩展运算符。
      猜你喜欢
      • 2019-02-18
      • 2022-10-07
      • 2019-07-15
      • 1970-01-01
      • 2019-12-11
      • 1970-01-01
      • 1970-01-01
      • 2015-08-14
      • 2023-04-05
      相关资源
      最近更新 更多