【问题标题】:NestJS returning the result of an HTTP requestNestJS 返回 HTTP 请求的结果
【发布时间】:2018-10-25 14:38:45
【问题描述】:

在我的 NestJS 应用程序中,我想返回 http 调用的结果。

按照NestJS HTTP module的例子,我所做的只是:

import { Controller, HttpService, Post } from '@nestjs/common';
import { AxiosResponse } from '@nestjs/common/http/interfaces/axios.interfaces';
import { Observable } from 'rxjs/internal/Observable';

@Controller('authenticate')
export class AuthController {

  constructor(private readonly httpService: HttpService) {}

  @Post()
  authenticate(): Observable<AxiosResponse<any>> {
    return this.httpService.post(...);
  }
}

但是从客户端我得到 500 并且服务器控制台说:

TypeError:将循环结构转换为 JSON 在 JSON.stringify() 在 stringify (/Users/francesco.borzi/sources/business-controller-rewrite/node_modules/express/lib/response.js:1119:12) 在 ServerResponse.json (/Users/francesco.borzi/sources/business-controller-rewrite/node_modules/express/lib/response.js:260:14) 在 ExpressAdapter.reply (/Users/francesco.borzi/sources/business-controller-rewrite/node_modules/@nestjs/core/adapters/express-adapter.js:41:52) 在RouterResponseController.apply (/Users/francesco.borzi/sources/business-controller-rewrite/node_modules/@nestjs/core/router/router-response-controller.js:11:36) 在 在 process._tickCallback (internal/process/next_tick.js:182:7)

【问题讨论】:

  • 可能 httpService 返回了一些无效的 JSON,而 NestJS (Express) 会因为无法转换而抛出错误。尝试用 httpService 调用一些简单的东西,也许是简单的测试 GET。
  • 据我了解,NestJS 应该会自动转换为 json.. 对吗?
  • 是的,它应该默认自动转换。
  • 当我遇到同样的事情时,我尝试使用另一个我 100% 肯定的来源进行测试,它返回有效的 json,但它仍然给出相同的错误。使用 GET 时结果相同。

标签: node.js typescript rxjs axios nestjs


【解决方案1】:

问题似乎源于我们试图直接返回一个 Response 对象,这本质上是循环的。我不确定实现这一点的正确方法,但我能够通过直接使用 axios 来绕过它,解开 promise 并只返回数据。

@Post('login')
  async authenticateUser(@Body() LoginDto) {
    const params = JSON.stringify(LoginDto);

    return await axios.post('https://api.example.com/authenticate_user',
      params,
      {
        headers: {
          'Content-Type': 'application/json',
        },
      }).then((res) => {
          return res.data;
    });
}

更新

我意识到我可以使用新的 rxjs 管道方法对从 httpService 返回的 Observable 执行相同的操作,所以这可能是更好的方法。

@Post('login')
async authenticateUser(@Body() LoginDto) {
    const params = JSON.stringify(LoginDto);

    return this.httpService.post('https://api.example.com/authenticate_user',
      params,
      {
        headers: {
          'Content-Type': 'application/json',
        },
      }).pipe(map((res) => {
    return res.data;
  }));
}

【讨论】:

  • @andyrune。抱歉,我只是想指出异步等待不适用于 Observables。它仅适用于承诺。我相信你必须将你的 observable 转换为一个 promise,然后使用 async/await。
  • @andyrune,为什么控制器在这里,调用 api 并点击另一个 api,而不是直接从数据库返回数据?
  • @MuhammedMoussa 在我的情况下,身份验证 api 在不同的服务器上。
  • 这行得通,但 imo 真的很难看。为什么以这种奇怪的方式实现 http 请求?
  • 当我尝试 console.log 响应时没有得到任何响应
【解决方案2】:

此问题来自 axios 库。为了解决这个问题,你必须拉出data 属性:

return this.httpService.post(...)
  .pipe(
    map(response => response.data),
  );

【讨论】:

  • 所以我必须在我的 on 上学习这个。但是现在我想在出错的情况下推送原始的 HTTP 状态代码。有什么建议吗?
  • 非常感谢,今天还没有修复
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-01
  • 2012-04-28
相关资源
最近更新 更多