在控制器中处理 HTTP 响应

Processing HTTP response in the controller

我正在尝试调用 REST API - 例如 https://randomuser.me/api/ 并使用 Axios 记录响应并将其保存到 NestJS 中的文件中。

其余调用在服务 class 中,而后者又从控制器访问。

import { Injectable, Logger } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { AxiosResponse } from 'axios';
import { Observable} from 'rxjs';

import fs = require('fs')
import { map } from 'rxjs';

@Injectable()
export class RandomuserService {
    constructor(
        private httpService: HttpService
    ) {}
    
    private logger = new Logger(RandomuserService.name)

    // Send JSON Bundles to the FHIR Server
    async getRandomuser(): Promise<Observable<AxiosResponse<any>>> {
        try {
           return this.httpService.get('https://randomuser.me/api/').pipe(map(response => response.data)); 
        }
        catch (err) {
            this.logger.error(`Error in calling RandomUser RSET API end point: ${err}`)
        }
    }

.
.
    // save the json response to file
    writeToFile(data: any, fileName: string) {
     ...
    }

}

并且正在从 Controller 访问此 getRandomuser()

// Get Randomuser
@Get()
async getRandomuser(): Promise<any> {
    try {
        let result = await this.randomuserService.getRandomuser()
        const jsonString = JSON.stringify(result, null, 2)
        this.logger.log(`The Randomuser result1 : ${result}`)
        this.logger.log(`The Randomuser result2 : ${jsonString}`)
        return result
    }
    catch (err) {
        this.logger.error(`Error in obatining the Randomuser result from RandomuserService class : ${err}`)
    }
}

从连接到 http://localhost:3333/ 的浏览器我得到响应:

{"results":[{"gender":"male","name":{"title":"Monsieur","first":"Renzo","last":"Rousseau"},"location":{"street":{"number":5368,"name":"Rue Docteur-Bonhomme"},"city":"Nesslau","state":"Bern","country":"Switzerland","postcode":8221,"coordinates":{"latitude":"-55.2927","longitude":"-143.8486"},"timezone":{"offset":"-12:00","description":"Eniwetok, Kwajalein"}},"email":"renzo.rousseau@example.com","login":{"uuid":"de08b93c-9879-40cd-9671-738dcc659eed","username":"lazybutterfly535","password":"glacier","salt":"JHBMcY2v","md5":"061daa26038881e9c554230d56d9cf17","sha1":"4e4ee22ffb6433599109a5a84d051f6812b21c01","sha256":"262d628c486f014c4be28456f74a56344f9a3fcce457541764e962b00601f393"},"dob":{"date":"1956-04-19T17:30:24.905Z","age":65},"registered":{"date":"2011-05-17T15:38:03.695Z","age":10},"phone":"078 336 99 84","cell":"079 578 23 53","id":{"name":"AVS","value":"756.8704.7049.02"},"picture":{"large":"https://randomuser.me/api/portraits/men/85.jpg","medium":"https://randomuser.me/api/portraits/med/men/85.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/85.jpg"},"nat":"CH"}],"info":{"seed":"dd592dab2501b022","results":1,"page":1,"version":"1.3"}}

但是,当我尝试在记录器或控制台中打印响应时,我得到的是空对象。

Nest] 68352  - 11/05/2021, 4:07:45 PM     LOG [RandomuserController] The Randomuser result1 : [object Object]
[Nest] 68352  - 11/05/2021, 4:07:45 PM     LOG [RandomuserController] The Randomuser result2 : {
  "source": {}
}

我应该如何记录完整的响应?如何将响应保存到文件? (现在只保存 {"source": {}}

Nest 的 HttpService returns 一个 RxJS Observable 有点像增压回调。默认情况下 await 不适用于 Observable,但如果您最终从控制器发回一个 Observable,Nest 将处理该 Observable。为了能够 await observable,您需要将 observable 包装在 rxjslastValueFrom 方法中。如果你只想在整个调用中使用 Observables,那么你需要使用 .piperxjs/operators,可能 tap 用于日志记录。像这样的事情应该做

@Get()
async getRandomuser(): Observable<any> {
  return this.randomuserService.getRandomuser().pipe(
    tap((data) => {
      const jsonString = JSON.stringify(data, null, 2);
      this.logger.log(`The Randomuser result1 : ${data}`)
      this.logger.log(`The Randomuser result2 : ${jsonString}`)
    }),
    catchError(err => {
      this.logger.error(`Error in obatining the Randomuser result from RandomuserService class : ${err}`)
      throwError(err);
    })
  )
}