NestJS 与 Apollo 数据源
Posted
技术标签:
【中文标题】NestJS 与 Apollo 数据源【英文标题】:NestJS with Apollo DataSource 【发布时间】:2020-11-04 12:48:42 【问题描述】:我一直在尝试使用 NestJS 重新创建 Apollo tutorial。但是当我尝试将apollo-datasource-rest
与 NestJS 一起使用时,从外部数据源获取数据时失败,并出现以下错误:
[Nest] 29974 - 07/14/2020, 9:33:20 PM [ExceptionsHandler] Cannot read property 'fetch' of undefined +125971ms
TypeError: Cannot read property 'fetch' of undefined
似乎数据源类没有被正确注入到解析器中,但我不知道为什么?
// The data source class
@Injectable()
class LaunchAPI extends RESTDataSource
constructor()
super();
this.baseURL = 'https://api.spacexdata.com/v2/';
async getLaunchById( launchId )
return await this.get('launches', flight_number: launchId );
// The Nest resolver
@Resolver('launch')
@Injectable()
export class LaunchResolver
constructor(private readonly launchAPI: LaunchAPI)
@Query('getLaunch')
async getLaunch(
@Args('id') id: string
)
return await this.launchAPI.getLaunchById( launchId: id )
// The app module
@Module(
imports: [
GraphQLModule.forRoot(
dataSources,
context: ( req ) =>
if (req)
return headers: req.headers ;
,
typePaths: ['./**/*.graphql'],
definitions:
path: join(process.cwd(), 'src/graphql.schema.ts'),
outputAs: 'class',
,
debug: true,
)
],
controllers: [AppController],
providers: [AppService, LaunchAPI, LaunchResolver],
)
export class AppModule
将 Apollo 的数据源与 Nest 解析器结合使用的最佳方式是什么?
【问题讨论】:
【参考方案1】:我能够通过在我的每个解析器方法上使用 @Context
装饰器来解决问题,以便获取 apollo 数据源服务(例如 dataSources
),而不是在解析器类中注入数据源。所以更新后的样子如下:
// The Nest resolver
@Resolver('launch')
@Injectable()
export class LaunchResolver
@Query('getLaunch')
async getLaunch(
@Context('dataSources') launchAPI : DataSources,
@Args('id') id: string
)
return await launchAPI.getLaunchById( launchId: id )
// app.module.ts
// set up any dataSources our resolvers need
const dataSources = () => (
launchAPI: new LaunchAPI(),
);
@Module(
imports: [
GraphQLModule.forRoot(
dataSources,
context: ( req ) =>
if (req)
return headers: req.headers ;
,
typePaths: ['./**/*.graphql'],
definitions:
path: join(process.cwd(), 'src/graphql.schema.ts'),
outputAs: 'class',
,
debug: true,
)
],
controllers: [AppController],
providers: [AppService, LaunchAPI, LaunchResolver],
)
export class AppModule
【讨论】:
如果您的 Resolver 和 RestDataSource IE 之间有一个服务层,您将如何解决此问题:Resolver --> BL Service --> RestDataSource? 这种方法存在一些问题。照原样,1. 您无法在 LaunchAPI 中正确利用 DI,因为它手动添加为数据源并在 DI 上下文之外。 2. LaunchAPI 设置为单例范围。它应该是请求范围,但最终它是无关紧要的,因为在这种方法中完全绕过了 DI。以上是关于NestJS 与 Apollo 数据源的主要内容,如果未能解决你的问题,请参考以下文章
通过 Apollo Server (NestJS) 处理异常
如何使用 NestJS GraphQL 实现 NuxtJS Apollo
Nestjs 中的 Graphql Apollo 上传返回无效值