【问题标题】:How to use NestJS to get data from 3rd-party API如何使用 NestJS 从 3rd-party API 获取数据
【发布时间】:2020-08-10 10:49:42
【问题描述】:

我最近开始学习 NestJS,因为它似乎是一个很棒的框架,可以帮助我构建项目的后端。我需要学习并且很难找到的是一种从 3rd-party API 获取数据的方法。根据文档,它包装了 Axios,这很棒,因为我非常了解 Axios。我无法理解的是如何让它工作。

出于学习目的,我正在尝试从 OpenWeatherMap.org 获取天气数据。当我搭建应用程序时,我使用了nest new weather-app,并依次生成了一个天气模块、服务和控制器,以确保一切都与nest g <<<type of file>>> weather 正确集成。您可以放心地假设我的app.module.ts 正确导入了我的weather.module.ts。此外,我的 OpenWeatherMap API 密钥直接复制到我的.env

这是我的weather.module.ts

require('dotenv').config();
import { Module, HttpModule } from '@nestjs/common';
import { WeatherService } from './weather.service';
import { WeatherController } from './weather.controller';

@Module({
  imports: [
    HttpModule.register({
      baseURL: 'api.openweathermap.org/data/2.5/weather',
      params: {
        appid: process.env.OPEN_WEATHER_KEY,
      },
    }),
  ],
  providers: [WeatherService],
  controllers: [WeatherController],
})
export class WeatherModule {}

这是我的weather.service.ts

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

@Injectable()
export class WeatherService {
  constructor(private readonly httpService: HttpService) {}

  forCity(city: string): Observable<AxiosResponse<object>> {
    return this.httpService.get(`?q=${city}`);
  }
}

这是我的weather.controller.ts:

import { Controller, Get, Param } from '@nestjs/common';
import { WeatherService } from './weather.service';

@Controller('weather')
export class WeatherController {
  constructor(private readonly weatherService: WeatherService) {}

  @Get(':city')
  getWeather(@Param('city') city: string): object {
    return this.weatherService.forCity(city);
  }
}

当我运行这个项目时,Nest 成功地构建了所有内容而没有错误。然而,当我去 Postman 并尝试达到我的终点时,我得到了这个:

我认为我已经相当密切地关注了 NestJS 文档,并使用了我自己在 Axios 方面的经验,但我无法弄清楚我在这里做错了什么。我有一个更大的项目,我想在其中使用 Nest,但我需要使用 3rd-party API 才能使该项目工作。

有什么想法吗?

提前致谢!

更新: 使用 Observable 的pipe 方法和catchError 后,我得到了401 状态。起初,我认为这意味着我的 api 密钥没有正确传递,但我将其注销,它与我的天气 api 帐户中的内容相匹配。

第二次更新:几天后(包括晚上休息),我仍然没有任何成功。如果我将我的 url 和 API 密钥移动到weather.services.ts,我会得到一个循环引用。我已经彻头彻尾地阅读了 Nest 和 Axios 的文档,但我仍然无法让它发挥作用。

我还尝试访问 Nest 通过 HttpService 公开的 axiosRef(),但最终得到一个 Typescript 编译错误,将我的 Observable 类型转换为 Promise。所做的只是给了我另一个循环引用。

【问题讨论】:

  • 您的代码在我看来是正确的。您应该在Observable.pipe() 方法中添加一个catchError 运算符来尝试查看错误是什么。一旦你弄清楚了,提供帮助会更容易
  • @JayMcDoniel,我现在收到ECONNREFUSED 127.0.0.1:80 错误,所以我现在知道它不喜欢在我的 localhost:8080 上使用某些东西。但是,我不确定 8080 端口在哪里使用。我的印象是 NestJS 使用 3000 端口。
  • 我得到了那个错误,但现在我得到了状态 401 返回。我仔细检查了一下,我的 api 密钥通过代码就可以了。
  • 如果您收到 401,则听起来您正在对 API 进行未经授权的调用。我相信您可能正在使用 params 键设置 URL 参数,而不是查询参数。我在axios 的文档中没有看到任何关于设置全局查询参数的内容。
  • 好吧,我知道这不是 api 密钥。我可以通过 Postman 从 api 获得响应。我将不得不查看 Nest 和 Axios 的文档,看看我能找到什么。

标签: axios nestjs


【解决方案1】:

HttpModule 和 HttpService(来自“@nestjs/common”包)已被弃用,并将在下一个主要版本中删除。请改用“@nestjs/axios”包。

app.module.ts

import { HttpModule } from '@nestjs/axios';

@Module({
  imports: [
    HttpModule,
  ],
})
export class AppModule {}

app.controller.ts

@Get()
getWeatherForecasts() {
   return this.appService.getWeatherForecasts();
}

app.service.ts

import { HttpService } from '@nestjs/axios';
import { firstValueFrom } from 'rxjs';

async getWeatherForecasts() {
   const url = 'http://www.7timer.info/bin/api.pl?lon=113.17&lat=23.09&product=astro&output=json';
   const { data } = await firstValueFrom(this.httpService.get(url));
   return data;
}

【讨论】:

  • 我使用 firstValueFrom 因为 toPromise() 也被弃用了
  • 最佳答案^,工作就像一个魅力
【解决方案2】:

在您的服务中,当您返回输出时,NestJS 会尝试“字符串化”类型为 Observable 的输出。这将导致错误,因为上面的返回类型是循环结构。我建议通过管道响应。

试试这个weather.service.ts

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

@Injectable()
export class WeatherService {
  constructor(private readonly httpService: HttpService) {}

  forCity(city: string): Observable<AxiosResponse<object>> {
    return this.httpService
      .get(`?q=${city}`)
      .pipe(
         map((axiosResponse: AxiosResponse) => {
           return axiosResponse.data;
         }),
      );
  }
}

【讨论】:

    猜你喜欢
    • 2017-01-04
    • 1970-01-01
    • 2019-04-21
    • 1970-01-01
    • 2014-08-26
    • 2021-11-18
    • 2021-09-19
    • 2018-06-19
    • 1970-01-01
    相关资源
    最近更新 更多