我正在构建一个NestJS api,需要调用外部api并解析响应数据。这是一个healthCheck,用于查看是否有另一个API启动并运行。下面是基本调用:
@Get('healthCheck')
public async healthCheck(
@Req() req: Request,
@Res() res: Response,
)
{
const obj = this.test(req);
console.log(obj)
}
test(req) {
const testingURL = 'https://google.com';
return this.http.get(testingURL).pipe(
map((obj: AxiosResponse) => { return obj.data } ),
tap(console.log)
);
}
我过去经常使用angular,并且使用过各种各样的".toPromise()"或"订阅()";将循环结构转换为JSON"
当前console.log(obj)"在第一部分中打印出一个无法解析的可观察对象:
Observable {
source: Observable {
source: Observable { _subscribe: [Function (anonymous)] },
operator: [Function (anonymous)]
},
operator: [Function (anonymous)]
}
任何建议或有用的提示将是有帮助的。大多数讨论这个问题的帖子都说,简单地映射响应或添加一个承诺就可以解决这个问题,但它没有进一步解释如何解析这个可观察对象,一旦它被获取。
编辑:解决方案张贴在下面。
感谢https://stackoverflow.com/users/9576186/jay-mcdoniel在这方面的帮助和这个项目参考https://github.com/jmcdo29/heart-watch/blob/feat/nest-commander/src/character-reader/character-reader.api.service.ts
这是我的工作解决方案:
@Get('healthCheck')
public async healthCheck() {
const obj = await this.getEndpoint('https://google.com');
console.log(obj);
}
private getEndpoint(url): Promise<any> {
return lastValueFrom(
this.http.get<any>(url).pipe(
map((res) => {
return res.data;
}),
),
);
}
这应该解析任何get(或post)端点,只要不需要parameters/auth,并返回使用axios在nestjs中解析为promise的可观察对象。
编辑:正如Jay建议的那样,使用lastValueFrom而不是deprecation toPromise()
-
除非你有理由,否则不要将
@Res()
注入路由处理程序,只需返回你的数据并让Nest处理它而不必调用res.send()
。如果您需要访问响应头或设置cookie,请使用@Res({ passthrough: true })
-
你可以直接在Nest中返回一个可观察对象,Nest会处理读取数据并为你返回。
-
如果你需要读取可观察对象中的值,你可以使用RxJS和
pipe(tap(console.log))
中的tap
操作符来读取数据
编辑10/15/2021
现在我也读到你想在另一个API调用中使用这个数据,你有两个选择:
-
使用
lastValueFrom
将RxJS可观察对象转换为Promise
,以便它可以被await
编辑。 -
使用
mergeMap
或switchMap
这样的操作符,将你的可观察对象链接在一起,最后仍然返回单个可观察对象。RxJS就像非常强大的回调,上面有额外的选项,但它们也可能变得复杂,所以这个选项通常需要更多的细微差别和奉献,以确保操作符被正确链接。
您应该从HttpModule
(@nestjs/axios
)注入HttpService
,并获得像这样的axios引用this.httpService.axiosRef.get(...)
详情请参阅官方文档