警告以下代码是不正确的数据源,需要根据请求创建。
请勿使用以下代码
我正在尝试使用 apollo-rest-datasource
使用 NestJS。我看到的缺点是数据源不参与 NestJS 的 DI 系统。
我能够通过让 NestJS 实例化单例数据源然后使用 GraphQLModule.forRootAsync
将这些实例注入(inject) Apollo Server 的 dataSources
属性来解决这个问题。
GraphQLModule.forRootAsync({
imports: [
DataSourcesModule
],
useFactory: (...args: DataSource[]) => {
return {
typePaths: ['./**/*.graphql'],
context: ({req}: {req: Request}) => ({ token: req.headers.authorization }),
playground: true,
dataSources: () => {
let dataInstances = {} as any;
args.forEach(arg => {
const dataSource = arg as any;
dataInstances[dataSource.constructor.name] = arg;
});
return dataInstances;
},
};
},
inject: [...dataSources]
我现在让 DI 在我的 DataSource 中工作,并且可以在解析器中使用 DI 来包含我的 DataSource 实例(而不是从 GraphQL 上下文访问)。虽然这有效,但感觉不对。
NestJS 的 DI 和 Apollo GraphQL 上下文是否有更好的方法?
最佳答案
RESTDataSource 看起来只是一个普通的类。您应该能够简单地应用 @Injectable()
装饰器并将它们视为常规 Nest 服务。这将允许您将依赖项注入(inject)到它们中,并将数据源注入(inject)到您的解析器中,而无需像您所展示的那样在 GraphQLModule 中引导事物。
const { RESTDataSource } = require('apollo-datasource-rest');
import { Injectable } from '@nestjs/common';
@Injectable()
class MoviesAPI extends RESTDataSource {
// Inject whatever Nest dependencies you want
constructor(private readonly someDependency: SomeDependency) {
super();
this.baseURL = 'https://movies-api.example.com/';
}
async getMovie(id) {
return this.get(`movies/${id}`);
}
async getMostViewedMovies(limit = 10) {
const data = await this.get('movies', {
per_page: limit,
order_by: 'most_viewed',
});
return data.results;
}
}
@Injectable()
class ResolverClass {
// Inject your datasources
constructor(private readonly moviesApi: MoviesAPI) { }
}
您只需确保将您的 DataSource 类放入适当的 Nest 模块的提供者中,如果它们也需要从其他模块使用,则可以选择导出它们。
更新:
由于还需要将数据源传递到 ApolloServer 中,因此您可以通过引入自己的装饰器以应用于每个数据源,然后使用反射来“发现”应用程序中存在的所有源,从而以更 Nest-y 的方式实现这一点。这不是目前记录良好的内容,但您可以查看一些 Nest 源代码中的示例,了解如何完成此操作。 For reference here's the code that discovers all of the @Resolver
decorated classes for the GraphQL module .
它基本上归结为使用 ModulesContainer
和 MetadataScanner
来查找应用程序中存在的所有提供程序,然后过滤以查找哪些应用了您的自定义装饰器。 (例如 @DataSource()
)。
我认为您现在拥有的不一定是大问题,但如果您以这种方式实现它,您就不必担心每次都要记住添加新的数据源。
关于typescript - NestJS GraphQL 数据源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54517872/