Nest 实现天气预报查询服务
点击公众关注号,“技术干货”及时达!今天我们实现了一个查询城市天气预报的服务。
使用和风天气的免费 api。
免费的接口一天可以请求1000次,自己的项目就足够用了:
最多可以查询未来7天的天气预报。
首先,登录和风天气,
然后在用户中心绑定邮箱和手机号:
之后进入控制台,点击创建项目:
这里大家选择免费订阅(我其他项目用了,免费名额了),指定密钥的名字:
然后就可以看到你的key了:
如果我们要查询青岛未来7天的天气。
需要先查询青岛的id:
location是城市名字的拼音,然后带上刚才的钥匙:
https://devapi.qweather.com/v7/weather/7d?location=101120606&key=aff40f07926348b9b06f3229d2b52e6a
返回了青岛市和各个区的信息。
有了城市id之后就可以查询天气了:
https://api.qweather.com/v7/weather/7d?location=101120201&key=187d6c3dd15f4d2d99e2a7e0ee08ba04
这里返回了从 2024-5-1 到 2024-5-7 的天气。
具体字段的解释可以看文档:
这样我们就实现了查询某个城市7天天气的功能。
还有问题,现在是先用城市的拼音查的id,再用id查的天气。
那直接让用户输入城市拼音么?
这样也不好,我们可以用拼音这个包:
它可以获得中文的拼音:
这样,整个流程就串起来了。
当然,如果您让用户直接选择城市,然后查询城市的天气,这样就可以获得所有城市的信息了。
网上有很多这样的JSON数据的:
有所有城市名称及其 ID。
理清思路了,我们来写下代码:
npm install -g @nestjs/cli
nest new city-weather
安装拼音包及其类型:
npm install --save pinyin@alpha
npm install --save-dev @types/pinyin
然后我们加个接口测试下:
@Get('pinyin')
pinyin(@Query('text')text:string){
returnpinyin(text).join('')
}
把服务运行起来:
npm run start:dev
访问下一个试用:
可以看到,确实返回了拼音。
但我们不需要知道是几声。
修改参数:
这样就好了:
那么nest服务里怎么访问三方接口呢?
直接用 axios 什么?
可以,但是我们希望统一配置 axios,然后各个模块都用同一个 axios 实例。
所以用@nestjs/axios这个包:
npm install --save @nestjs/axios axios
在AppModule中引入下HttpModule:
这里可以填入各种请求配置,比如baseURL等,其实就是new了一个axios实例:
然后在已使用的位置注入httpService:
@Inject(HttpService)
privatehttpService:HttpService;
@Get('weather/:city')
asyncweather(@Param('city')city:string){
constcityPinyin=pinyin(city,{style:'normal'}).join('');
const{data}=awaitfirstValueFrom(
this.httpService.get(`https://geoapi.qweather.com/v2/city/lookup?location=${cityPinyin}&key=187d6c3dd15f4d2d99e2a7e0ee08ba04`)
)
returndata;
}
使用@Param取路径中的参数。
然后用拼音获取城市的拼音,然后调用和风天气的接口。
这里为啥用firstValueFrom的rxjs操作符呢?
因为 HttpModule 把 axios 的方法返回值封装成了 rxjs 的 Observerable。
好处是你可以用 rxjs 的操作符了。
坏处是转成promise还得加一层firstValueFrom。
它就是用来把 rxjs Observable 转成 Promise 的:
测试下:
没啥问题。
然后继续调用天气预报:
@Get('weather/:city')
asyncweather(@Param('city')city:string){
constcityPinyin=pinyin(city,{style:'normal'}).join('');
const{data}=awaitfirstValueFrom(
this.httpService.get(`https://geoapi.qweather.com/v2/city/lookup?location=${cityPinyin}&key=187d6c3dd15f4d2d99e2a7e0ee08ba04`)
)
constlocation=data?.['location']?.[0];
if(!location){
thrownewBadRequestException('没有对应的城市信息');
}
const{data:weatherData}=awaitfirstValueFrom(
this.httpService.get(`https://api.qweather.com/v7/weather/7d?location=${location.id}&key=187d6c3dd15f4d2d99e2a7e0ee08ba04`)
)
returnweatherData;
}
如果没有查到位置,返回 400 错误。
否则用location.id 查询该城市天气预报。
这样,我们的城市天气预报服务就完成了。
案例代码 上传了小册仓库
总结我们基于和风天气的api实现了天气预报查询服务。
主要用了这个拼音包来完成中文转拼音,然后用拼音去请求和风的api查询城市id。
接下来用城市 id 请求天气数据。
和风天气的api免费版一天可以调用1000次,足够用了。
Nest 里发送 http 请求,我们用的是 @nestjs/axios 包的 HttpModule 的。
它可以统一配置,然后注入 HttpService 到可用的地方,并且 httpService 方法的返回值消耗成了 rxjs 的 Observerable,可以直接使用 rxjs 的操作符。
比喻用fistValueFrom来把rxjs的Observable转为Promise。
这样,您就可以在您的应用中集成提醒功能了。
点击公众关注号,“技术干货”及时达!
阅读原文
网站开发网络凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设、网站改版、域名注册、主机空间、手机网站建设、网站备案等方面的需求...
请立即点击咨询我们或拨打咨询热线:13245491521 13245491521 ,我们会详细为你一一解答你心中的疑难。 项目经理在线