【发布时间】: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 的文档,看看我能找到什么。