NestJS API 在 API 内调用和读取响应数据

NestJS API calls and reading response data within the API

我正在构建 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()”或“subscribe()”会导致“将循环结构转换为 JSON".

目前第一节中的“console.log(obj)”正在打印出一个无法解析的可观察对象:

Observable {
  source: Observable {
    source: Observable { _subscribe: [Function (anonymous)] },
    operator: [Function (anonymous)]
  },
  operator: [Function (anonymous)]
}

任何建议或有用的提示都会有所帮助。大多数讨论此问题的其他帖子都说简单映射响应或添加承诺可以解决问题,但它没有进一步解释如何在获取可观察对象后对其进行解析。

编辑:下面发布了解决方案。

  1. 除非你有理由,否则不要将 @Res() 注入路由处理程序,只需 return 你的数据并让 Nest 处理它而不是必须调用 res.send()。如果您需要访问响应 headers 或设置 cookie,请使用 @Res({ passthrough: true })

  2. 您可以 return 直接在 Nest 中观察一个对象,Nest 会处理读取数据并将其发回给您。

  3. 如果你需要读取 observable 中的值,你可以使用 RxJS 中的 tap 运算符和 pipe(tap(console.log)) 来读取数据


编辑 2021 年 10 月 15 日

现在我还了解到您想要在另一个 API 调用中使用此数据,您有两个选择:

  1. 使用 lastValueFrom 将 RxJS Observable 转换为 Promise 以便可以 awaited。简单易用

  2. 使用 mergeMapswitchMap 等运算符并将您的 Observable 链接在一起,最后仍然 return 一个单独的 observable。 RxJS 就像真正强大的回调,在顶部有额外的选项,但它们也可能变得复杂,所以这个选项通常需要更多的细微差别和奉献精神,以确保运算符被正确链接。

感谢https://whosebug.com/users/9576186/jay-mcdoniel for help on this and this project reference 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 不是必需的,并且 return observable 使用 axios 在 nestjs 中解析为一个 promise。

编辑:正如 Jay 所建议的,使用 lastValueFrom 而不是 depricated toPromise()