我最近开始学习 NestJS,因为它似乎是一个很棒的框架,可以帮助构建我的项目的后端。我需要学习但找不到的是一种从 3rd-party API 获取数据的方法。根据文档,它包装了 Axios,这很棒,因为我非常了解 Axios。我无法理解的是如何让它发挥作用。
出于学习目的,我正在尝试从 OpenWeatherMap.org 获取天气数据。当我搭建应用程序的脚手架时,我nest new weather-app按顺序使用并生成了天气模块、服务和控制器,以确保所有内容都与nest g <<<type of file>>> weather. 您可以放心地假设 myapp.module.ts正确weather.module.ts导入了 my 。此外,我的 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 {}
Run Code Online (Sandbox Code Playgroud)
这是我的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}`);
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的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);
}
}
Run Code Online (Sandbox Code Playgroud)
当我运行这个项目时,Nest 成功构建了所有内容,没有错误。然而,当我转到 Postman 并尝试到达终点时,我得到以下信息:
我想我已经相当仔细地遵循了 NestJS 文档,并利用了我自己使用 Axios 的经验,但我无法弄清楚我在这里做得不正确。我有一个更大的项目,我想在其中使用 Nest,但我需要使用第 3 方 API 才能使该项目正常工作。
有任何想法吗?
提前致谢!
更新:使用 Observable 的pipe方法 和后catchError,我得到了401状态。起初,我认为这意味着我的 api 密钥没有正确传递,但我将其注销,它与我的天气 api 帐户中的内容相匹配。
第二次更新:几天后(包括一个晚上的休息),我仍然没有取得任何成功。如果我将 url 和 API 密钥移至weather.services.ts,我会得到循环引用。我已经彻底阅读了 Nest 和 Axios 的文档,但感觉仍然无法使其正常工作。
我还尝试访问axiosRef()Nest 通过 公开的HttpService,但最终收到 Typescript 编译错误,将我的Observable类型转换为Promise. 所做的只是给了我另一个循环引用。
Dmi*_*nko 12
HttpModule 和 HttpService(来自“@nestjs/common”包)已被弃用,并将在下一个主要版本中删除。请改用“@nestjs/axios”包。
应用程序模块.ts
import { HttpModule } from '@nestjs/axios';
@Module({
imports: [
HttpModule,
],
})
export class AppModule {}
Run Code Online (Sandbox Code Playgroud)
应用程序控制器.ts
@Get()
getWeatherForecasts() {
return this.appService.getWeatherForecasts();
}
Run Code Online (Sandbox Code Playgroud)
应用程序服务.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;
}
Run Code Online (Sandbox Code Playgroud)
在您的服务中,当您返回输出时,NestJS 会尝试“字符串化” Observable<AxiosResponse>类型的输出。这会导致错误,因为上面的返回类型是循环结构。我建议通过管道传递响应。
尝试这个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;
}),
);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
14478 次 |
| 最近记录: |