【问题标题】:NestJS API calls and reading response data within the APINestJS API 调用和读取 API 内的响应数据
【发布时间】:2021-12-03 05:30:18
【问题描述】:

我正在构建一个 NestJS api,需要调用外部 API 并解析响应数据。这是一个运行状况检查,用于查看另一个 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)]
}

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

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

【问题讨论】:

    标签: node.js express axios nestjs endpoint


    【解决方案1】:

    感谢 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)端点,只要参数/auth 不是必需的,并使用 axios 在 nestjs 中返回解析为 promise 的 observable。

    编辑:正如 Jay 建议的那样,使用 lastValueFrom 而不是贬低 toPromise()

    【讨论】:

    • 请注意 toPromise 已弃用,不会在 RxJS v8 中使用。在 RxJS v7 及更高版本上使用 lastValueFrom(observable)
    【解决方案2】:
    1. 除非你有理由,否则不要将@Res() 注入到路由处理程序中,只需返回你的数据并让Nest 处理它,而不必调用res.send()。如果您需要访问响应标头或设置 cookie,请使用 @Res({ passthrough: true })

    2. 您可以直接在 Nest 中返回一个 observable,Nest 将处理读取数据并将其发回给您。

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


    编辑 2021 年 10 月 15 日

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

    1. 使用lastValueFrom 将RxJS Observable 转换为Promise,以便它可以awaited。直观且易于使用

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

    【讨论】:

    • 同意第 1/2 点。具体来说,我需要能够解析 API 本身中的数据,并将返回类似“res.write('Connection Made)”的内容(因此我将响应作为参数包含在内 - 我只是没有这样做部分)。对于 3,当我添加水龙头管道时,它会记录以下内容:“Observable { source: Observable { _subscribe: [Function (anonymous)] }, operator: [Function (anonymous)] }”(即一个可观察的对象)我不能解析/读取,如何解析这个可观察对象?希望这是有道理的,感谢您的帮助!
    • 您在map 运算符之后添加了tap,对吧?基本上,你不需要做console.log(observableObject),因为它不会返回任何有意义的东西
    • 我更新了代码 sn -p / 描述。它返回相同的可观察对象类型。
    • 您仍然在 healthCheck 代码中记录可观察对象。该方法只需要返回 observable,就像 test 一样。 Nest 将在后台使用 lastValueFrom 来获取数据
    • 我的问题可能不够清楚。我需要来自这个 API 调用的数据来进行另一个 API 调用(这两个调用都在这个系统之外)。我无法直接访问数据库,因此我需要进行 API 调用。换句话说,我需要在 healthCheck 方法本身中解析的可观察数据,以便我可以使用该数据作为参数调用另一个函数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-19
    • 2016-10-18
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多