首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >NestJS GraphQL DataSources

NestJS GraphQL DataSources
EN

Stack Overflow用户
提问于 2019-02-04 14:05:01
回答 2查看 3.3K关注 0票数 4

警告,下面的代码是不正确的,需要为每个请求创建DATASOURCES。

不使用下面的代码

我试图在apollo-rest-datasource中使用NestJS。我看到的缺点是DataSources不参与NestJS的DI系统。

通过让NestJS实例化单个数据源,然后使用GraphQLModule.forRootAsync将这些实例注入到阿波罗服务器的dataSources属性中,我就能够解决这个问题。

代码语言:javascript
运行
复制
 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和阿波罗GraphQL上下文?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-02-04 14:23:31

RESTDataSource看起来就像一个普通的类。您应该能够简单地应用@Injectable()装饰器,并将它们作为常规的Nest服务来处理。这将允许您将依赖项注入到它们中,也可以将DataSources注入到您的解析器中,而不需要像您已经展示的那样引导GraphQLModule中的东西。

代码语言:javascript
运行
复制
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模块的提供程序中,如果它们也需要从其他模块中使用,则可以选择导出它们。

更新:,因为dataSources也需要传递到ApolloServer中,所以您可以通过引入自己的装饰器来应用于每个DataSource,然后使用反射来“发现”应用程序中存在的所有源,从而以一种更适合的方式实现这一点。这一点目前还没有很好的文档化,但是您可以从Nest源代码中查看如何实现这一目标的示例。 decorated classes for the GraphQL module

它基本上可以归结为使用ModulesContainerMetadataScanner来查找应用程序中存在的所有提供程序,然后筛选哪些提供者已经应用了自定义装饰器。(例如,@DataSource())。

我不认为您现在拥有的东西一定是一个大问题,但是如果您要以这种方式实现它,您就不必担心每次都要添加新的dataSources。

票数 4
EN

Stack Overflow用户

发布于 2020-07-21 17:35:12

我能够通过在我的每个解析器方法上使用@Context装饰器来解决这个问题,以便获取数据源。给出一个例子here的完整答案。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54517872

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档