如何在其构造函数之外访问ApolloServer数据源?

时间:2019-11-20 11:56:06

标签: typescript graphql apollo-server

我正在使用apollo-datasource-rest从REST API中获取。从文档中,您可以集成如下数据源:

const server = new ApolloServer({
  typeDefs,
  dataSources: () => ({
    ds1: new Datasource1()
  }),
  resolvers: {
    Post: {
      comments: (post, _args, { dataSources }) => {
        dataSources.ds1.getComments(post.id)
      }
    }
  }
})

我的问题是我更喜欢使用类来实现解析器,因此对于Post我有这样的东西:

class Post {
  constructor(public id: number, public title: string, public content: string) {}

  comments() {
    return new Datasource1.getComments(this.id)
  }
}

我想知道是否支持? Datasource1的许多实例可以共享同一缓存吗?我不这么认为。 是否可以在其构造函数之外访问ApolloServer dataSources

1 个答案:

答案 0 :(得分:1)

自此再次出现在评论中。 GraphQL.js允许使用两种不同的方式来定义解析器。您可以使用纯数据对象,也可以在模式内部定义解析器逻辑。这是大多数人执行GraphQL的方式,因为这是大多数文档所显示的内容以及Apollo所宣扬的内容。第二种方法是您依赖默认的解析程序并创建数据访问对象。让我快速说明如何想象一个领域在概念上得到解决:

// When the field specifies a resolver
if (typeof fieldConfig.resolver !== 'undefined') {
  return fieldConfig.resolver(root, args, context, resolveInfo);
}
// When the field does not specify a resolver but the root value has a method with
// the same name
if (typeof root[fieldConfig.name] === 'function') {
  return root[fieldConfig.name](args, context, resolveInfo);
}
// Otherwise we return the value under the name with the potential of it being undefined
return root[fieldConfig.name];

因此,我们可以使用方法返回对象,就像OP对所有类型所做的一样。该对象包装静态属性,并具有用于需要参数或需要访问上下文的更复杂字段的方法。请注意在这种情况下如何不传递根值,因为该方法在根值上称为 on 。这意味着根值可以在方法内部以this的方式访问,就像我们从OOP一样。

直接回答问题:上下文可以作为resolver方法中的第二个参数访问。具体来说,我们可以编写以下代码:

class Post {
  constructor(public id: number, public title: string, public content: string) {}

  comments(_args, { datasources }) {
    return datasources.ds1.getComments(this.id)
  }
}