添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I'm trying to do what I think it's a stupid simple endpoint and some how it seems nestjs is not resolving the observable from Axios which results in the request hanging until it reaches the timeout. I've stripped down my entire application to barebones, literally, in the pursuit of the issue and I still can't really find anything....

main.ts:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(8080);
bootstrap();

app.module.ts:

import { Module } from '@nestjs/common';
import { AuthModule } from './auth/authModule';
@Module({
  imports: [AuthModule],
export class AppModule {}

AuthModule.ts:

import { Module } from '@nestjs/common';
import { AuthController } from './controllers/auth.controller';
import { HttpModule } from '@nestjs/axios';
@Module({
  controllers: [AuthController],
  imports: [HttpModule],
export class AuthModule {}

Auth.controller.ts:

import { Controller, Post } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { Observable } from 'rxjs';
import { AxiosResponse } from 'axios';
@Controller('auth')
export class AuthController {
  constructor(private httpService: HttpService) {}
  @Post('/login')
  login(): Observable<AxiosResponse<string>> {
    console.log('hit');
    return this.httpService.get<string>('http://auth-ms/health');

package.json:

 "dependencies": {
    "@liaoliaots/nestjs-redis": "^8.2.1",
    "@metamask/eth-sig-util": "^4.0.0",
    "@nestjs/axios": "^0.0.8",
    "@nestjs/common": "^8.0.0",
    "@nestjs/config": "^2.0.0",
    "@nestjs/core": "^8.0.0",
    "@nestjs/platform-express": "^8.0.0",
    "@nestjs/typeorm": "^8.1.4",
    "axios": "^0.27.2",
    "faker": "^6.6.6",
    "ioredis": "^5.0.3 || ^0.3.6",
    "jsonwebtoken": "^8.5.1",
    "jwt-decode": "^3.1.2",
    "nestjs-ethers": "^1.0.1",
    "nestjs-real-ip": "^2.1.0",
    "pg": "^8.7.3",
    "reflect-metadata": "^0.1.13",
    "rimraf": "^3.0.2",
    "rxjs": "^7.2.0",
    "typeorm": "^0.3.6",

Any clue on what's going on here? I guess I'm missing something small and stupid but... can't really figure out what.

So, AxiosResponse is a complex data structure and contains circular dependencies.

So you need to map it because you can't return it like this (except if you use a lib that parse circular JSON)

So you need to map the observable to only get the data of the website.

  @Post('/login')
  login(): Observable<string> {
    console.log('hit');
    return this.httpService
      .get<string>('http://auth-ms/health')
      .pipe(map((v) => v.data));
                We can also refer to most accepted answer in that thread: stackoverflow.com/questions/60908571/…
– Ali Emre Çakmakoğlu
                Sep 14, 2022 at 0:20

The Observable class works like a Promise and it handles I/O commands asynchronously by default. To return the result from a gateway request, like you are trying to do, you'll need to resolve the Observable synchronously.

To do it, you need to use the firstValueFrom or lastValueFrom functions from rxjs lib to convert it to a Promise and await the response:

import { Controller, Post } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { Observable, firstValueFrom } from 'rxjs';
import { AxiosResponse } from 'axios';
@Controller('auth')
export class AuthController {
  constructor(private httpService: HttpService) {}
  @Post('/login')
  async login(): Promise<string> {
    const responseObserver = this.httpService.get<string>('http://auth-ms/health');
    const response = await firstValueFrom(responseObserver);
    return response.data;
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.