Node.js 为接口编写Apollo解析器

Node.js 为接口编写Apollo解析器,node.js,graphql,apollo-server,apollostack,Node.js,Graphql,Apollo Server,Apollostack,假设我有以下类型的定义: interface Node { id: ID! } type Foo implements Node { id: ID! quantity: Int } type Bar implements Node { id: ID! name: String } 我发送的每个ID,我都希望以相同的方式处理。目前我需要一些解析器,如: { // ... 傅:{ id:(root)=>encodeId(root.id,root.type), // ...

假设我有以下类型的定义:

interface Node {
  id: ID!
}

type Foo implements Node {
  id: ID!
  quantity: Int
}

type Bar implements Node {
  id: ID!
  name: String
}
我发送的每个ID,我都希望以相同的方式处理。目前我需要一些解析器,如:

{
// ...
傅:{
id:(root)=>encodeId(root.id,root.type),
// ...
},
酒吧:{
id:(root)=>encodeId(root.id,root.type),
// ...
},
// ...
}
由于许多类型实现了
节点
,这会导致大量代码重复,开发人员很容易忘记正确的ID编码方式,或者忘记将它们全部编码在一起

有没有办法做这样的事

{
// ...
节点:{
__resolveType:(root)=>root.type,
id:(root)=>encodeId(root.id,root.type)
},
// ...
}

这样
Foo
Bar
节点的任何其他实现将继承
id
解析器?

这是一个有趣的问题。我不确定接口的冲突解决程序是否会接受除
\uu resolveType
以外的任何内容

我偶尔会遇到类似的情况,但我用默认和组合解析器修复了它

例如,对于节点,可以有以下默认解析程序:

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,
  },
}
这也有助于将解析器逻辑与解析器定义解耦。我建议随着项目的发展。您还可以在解析器组合中工作(请参阅)


您只需要确保您有权访问对象排列。无论如何,你应该这样做。这很有帮助。

这是一个有趣的问题。我不确定接口的冲突解决程序是否会接受除
\uu resolveType
以外的任何内容

我偶尔会遇到类似的情况,但我用默认和组合解析器修复了它

例如,对于节点,可以有以下默认解析程序:

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,
  },
}
这也有助于将解析器逻辑与解析器定义解耦。我建议随着项目的发展。您还可以在解析器组合中工作(请参阅)


您只需要确保您有权访问对象排列。无论如何,你应该这样做。这非常有用。

对于仍在这个问题上结结巴巴的人,您可以将
makeExecutableSchema
中的
inheritResolversFromInterfaces
标志设置为
true

在这里找到它:


Apollo documentation here:

对于仍在这个问题上结结巴巴的任何人,您可以将
makeExecutableSchema
中的
inheritResolversFromInterfaces
标志设置为
true

在这里找到它:


阿波罗文档:

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