1

假设我有以下 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)
  },
  // ...
}

这样FooBar以及任何其他实现Node将继承id解析器?

4

2 回答 2

5

对于仍然在此问题上遇到问题的任何人,您可以将inheritResolversFromInterfaces标志设置makeExecutableSchematrue.

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

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

于 2019-07-26T10:24:35.500 回答
3

这是个有趣的问题。我不确定接口的解析器是否会接受__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)。

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

于 2018-05-24T19:53:03.237 回答