site logo

Marico' space

nest.js 调用第三方api踩坑小计

Others 2024-08-31 17:02:20 457

近日部署了一个libretranslate服务,一个口碑不错开源机器翻译服务。就想着写个api去调用,于是参照nest.js 官方文档,开始了nest.js+axois入坑之旅。

1. 安装axois

yarn add @nestjs/axios axios

2. 引入HttpModule

// translator.module.ts

import { Module } from '@nestjs/common';
import { TranslatorService } from './translator.service';
import { TranslatorController } from './translator.controller';
import { HttpModule } from '@nestjs/axios';

@Module({
  imports: [HttpModule],
  controllers: [TranslatorController],
  providers: [TranslatorService],
})
export class TranslatorModule {}

3. 依据官方demo, 调用 libretranslate api, 结果报错

// translator.service.ts 

translate(text: string): Observable<AxiosResponse<any>> {
    return this.http.post(
      this.configService.translateUrl,
      {
        q: text,
        // ... ohter params
      }
    );
  }

调用api,报错如下:

[Nest] 2120  - 2024/08/31 16:10:16   ERROR [ExceptionsHandler] Converting circular structure to JSON
    --> starting at object with constructor 'ClientRequest'
    |     property 'res' -> object with constructor 'IncomingMessage'
    --- property 'req' closes the circle
TypeError: Converting circular structure to JSON

思考之下,原因也简单,httpService返回的是一个Observable,不能像Promise一样直接return, 即使.toPromise()也报错依旧,调用.subscribe(res => res.data) , 依然无法return出service。查询之后,发现Observable是基于rxjs,于是就有了将Observable最后的结果return的操作。

4. 修改写法,调用成功

// translator.service.ts

  async translate(text: string) {
    const res = this.http.post(
      this.configService.translateUrl,
      {
        q: text,
       // ...
      }
    );

    const checkResult: any = await lastValueFrom(res);
    return checkResult?.data;
  }

再次调用,完美输出。自此,坑被填,心已宽。