天气 API 接入实战:基于 ApiZero 实现实时天气、分钟级降水和 15 天预报查询
在很多业务系统中,天气数据并不是一个“装饰功能”,而是会直接影响用户体验和业务决策的数据能力。
例如,出行类应用需要展示实时天气和降水趋势;旅游系统需要提示景区天气和气象预警;物流系统需要关注暴雨、大风、低温等异常天气对配送的影响;农业、校园、社区、智慧城市类项目,也经常需要接入天气预报、空气质量、生活指数等数据。
如果开发者从零开始对接多个气象数据源,不仅要处理不同接口格式,还要考虑城市定位、实时天气、小时预报、未来多日预报、气象预警等多类数据的整合问题。使用统一的天气查询 API,可以明显降低开发和维护成本。
本文以 ApiZero 天气查询接口为例,整理一套适合实际项目落地的天气 API 接入方案,包含接口能力说明、请求方式、后端封装、前端展示、缓存策略、异常处理和安全建议。
接口地址:
https://v1.apizero.cn/api/weather工具页面:
https://apizero.cn/tools/weather一、为什么项目中需要天气查询接口
天气查询接口常用于这些场景:
| 使用场景 | 典型需求 |
|---|---|
| 出行应用 | 展示实时天气、降水概率、未来天气趋势 |
| 旅游系统 | 根据天气情况提示用户出行建议 |
| 物流配送 | 根据暴雨、大风、高温等天气调整配送策略 |
| 智慧城市 | 展示城市气象、空气质量、预警信息 |
| 农业系统 | 结合降水、温度、湿度辅助种植管理 |
| 校园/社区应用 | 展示本地天气和生活指数 |
| 数据看板 | 汇总多城市天气数据,辅助运营分析 |
天气接口的核心价值不只是“查天气”,而是把天气数据嵌入业务流程中,让系统可以根据实时气象变化做出更合理的展示、提醒和决策。
二、接口能力概览
ApiZero 天气查询工具支持实时天气、分钟级降水、逐小时预报、15 天预报和气象预警等能力。对于大多数 Web 项目、小程序、App 后端和数据看板来说,这些能力基本可以覆盖常见天气查询需求。
| 能力 | 说明 | 常见用途 |
|---|---|---|
| 实时天气 | 查询当前温度、湿度、天气现象、风速等 | 首页天气卡片、城市天气查询 |
| 分钟级降水 | 查询未来短时间内降水趋势 | 出行提醒、骑行提醒、配送预警 |
| 逐小时预报 | 查询未来多个小时的天气变化 | 分时天气曲线、活动安排 |
| 15 天预报 | 查询未来多日天气趋势 | 旅游计划、出行计划 |
| 气象预警 | 获取异常天气提示 | 应急提醒、风险提示 |
| 城市查询 | 按城市名或区域名查询天气 | 城市天气搜索、本地生活工具 |
建议开发者不要把天气接口只当成简单查询接口,而是按照“数据服务模块”来设计。这样后续扩展前端页面、缓存策略、预警通知和数据分析会更方便。
三、接口接入前的准备工作
接入天气接口前,需要先明确以下几个问题:
- 查询入口是城市名,还是经纬度?
- 前端是否需要展示实时天气?
- 是否需要展示未来 15 天预报?
- 是否需要分钟级降水提醒?
- 是否需要气象预警?
- 是否要把天气结果缓存到 Redis?
- API Key 是否只在后端保存?
- 异常时前端应该显示什么提示?
推荐的基础接入链路如下:
用户输入城市名 ↓ 前端提交查询请求 ↓ 后端调用天气接口 ↓ 后端统一格式化天气数据 ↓ 前端展示实时天气、预报和预警这种方式可以避免前端直接暴露密钥,也能方便后端统一做缓存、限流、日志和异常处理。
四、接口请求方式设计
天气接口地址如下:
https://v1.apizero.cn/api/weather实际项目中,建议通过后端调用接口,而不是让前端直接请求第三方接口。
1. curl 请求示例
以下示例用于说明常见调用方式,具体参数名称以实际接口文档为准。
curl-XGET"https://v1.apizero.cn/api/weather?city=北京&type=all"\-H"Authorization: Bearer your_api_key"常见参数可以设计为:
| 参数 | 是否必填 | 说明 |
|---|---|---|
| city | 是 | 城市名,例如北京、上海、广州、深圳 |
| type | 否 | 查询类型,例如 realtime、hourly、daily、all |
| days | 否 | 查询天数,例如 1、7、15 |
| lang | 否 | 返回语言,例如 zh_CN |
| unit | 否 | 温度单位,例如 metric |
如果项目只需要查询当前天气,可以使用实时天气类型;如果要做完整天气页,建议请求综合数据,然后由后端拆分成前端需要的模块。
2. 推荐请求类型
| 查询类型 | 适合场景 |
|---|---|
| realtime | 只展示当前温度、天气现象、湿度、风速 |
| minutely | 展示未来短时间降水趋势 |
| hourly | 展示逐小时温度、降水、风力变化 |
| daily | 展示未来多日天气预报 |
| all | 一次获取完整天气数据,适合天气详情页 |
如果是首页卡片,不建议每次请求完整数据;如果是天气详情页,可以请求完整数据并配合缓存使用。
五、Node.js 后端调用示例
下面以 Node.js 为例,演示如何在后端调用天气接口。
1. 安装依赖
npminstallaxios2. 基础调用代码
constaxios=require('axios');asyncfunctionqueryWeather(city){if(!city||!city.trim()){thrownewError('城市名称不能为空');}constapiKey=process.env.APIZERO_API_KEY;if(!apiKey){thrownewError('缺少 APIZERO_API_KEY 环境变量');}constresponse=awaitaxios.get('https://v1.apizero.cn/api/weather',{params:{city,type:'all'},headers:{Authorization:`Bearer${apiKey}`},timeout:8000});returnresponse.data;}queryWeather('北京').then(data=>{console.log('天气数据:',data);}).catch(error=>{console.error('天气查询失败:',error.message);});这段代码只适合演示。实际项目中,建议继续封装服务层,避免业务代码直接散落调用第三方接口。
六、封装天气查询服务
推荐在后端创建一个独立的天气服务类,例如WeatherService。
1. 服务封装示例
constaxios=require('axios');classWeatherService{constructor(){this.baseURL='https://v1.apizero.cn/api/weather';this.apiKey=process.env.APIZERO_API_KEY;}asyncqueryByCity(city,type='all'){this.validateCity(city);this.validateApiKey();try{constresponse=awaitaxios.get(this.baseURL,{params:{city,type},headers:{Authorization:`Bearer${this.apiKey}`},timeout:8000});returnthis.normalize(response.data);}catch(error){throwthis.handleError(error);}}validateCity(city){if(!city||!city.trim()){thrownewError('城市名称不能为空');}}validateApiKey(){if(!this.apiKey){thrownewError('接口密钥未配置');}}normalize(data){return{city:data.city||'',realtime:data.realtime||{},minutely:data.minutely||{},hourly:data.hourly||[],daily:data.daily||[],alerts:data.alerts||[]};}handleError(error){if(error.code==='ECONNABORTED'){returnnewError('天气接口请求超时');}if(error.response){returnnewError(`天气接口异常:${error.response.status}`);}returnnewError('天气接口请求失败');}}module.exports=WeatherService;2. 路由接口示例
constexpress=require('express');constWeatherService=require('./WeatherService');constrouter=express.Router();constweatherService=newWeatherService();router.get('/api/weather',async(req,res)=>{const{city,type}=req.query;try{constdata=awaitweatherService.queryByCity(city,type);res.json({success:true,data});}catch(error){res.status(400).json({success:false,message:error.message});}});module.exports=router;通过这种方式,前端只请求自己的业务后端:
/api/weather?city=北京&type=all真正的接口密钥只保存在服务端,安全性更高。
七、推荐返回结构设计
不同天气接口的原始返回结构可能比较复杂。为了让前端更容易使用,建议后端统一转换成稳定的数据格式。
示例结构:
{"city":"北京","realtime":{"temperature":26,"humidity":0.52,"weather":"多云","windDirection":"东北风","windSpeed":3,"aqi":48},"minutely":{"description":"未来两小时无明显降水","precipitation":[]},"hourly":[{"time":"2026-06-01 10:00:00","temperature":26,"weather":"多云","precipitation":0}],"daily":[{"date":"2026-06-01","weather":"多云","temperatureMin":20,"temperatureMax":30,"sunrise":"05:30","sunset":"19:22"}],"alerts":[{"title":"雷电黄色预警","level":"黄色","description":"预计未来短时间内可能出现雷电天气"}]}前端拿到这种结构后,可以直接拆成多个模块展示:
实时天气卡片 分钟级降水提示 逐小时天气折线图 15 天天气列表 气象预警卡片八、前端展示示例
1. 天气卡片 HTML
<divclass="weather-card"><divclass="city">北京</div><divclass="temperature">26℃</div><divclass="weather">多云</div><divclass="meta"><span>湿度:52%</span><span>空气质量:48</span></div></div>2. 天气卡片 CSS
.weather-card{width:320px;padding:20px;border-radius:12px;background:linear-gradient(135deg,#eef6ff,#ffffff);box-shadow:0 8px 24pxrgba(0,0,0,0.08);font-family:Arial,sans-serif;}.weather-card .city{font-size:18px;font-weight:600;color:#333;}.weather-card .temperature{margin-top:12px;font-size:42px;font-weight:700;color:#1677ff;}.weather-card .weather{margin-top:8px;font-size:16px;color:#555;}.weather-card .meta{margin-top:14px;display:flex;justify-content:space-between;font-size:13px;color:#666;}3. 前端请求示例
asyncfunctionloadWeather(city){constresponse=awaitfetch(`/api/weather?city=${encodeURIComponent(city)}&type=all`);constresult=awaitresponse.json();if(!result.success){thrownewError(result.message||'天气查询失败');}returnresult.data;}loadWeather('北京').then(data=>{console.log('实时天气:',data.realtime);console.log('15 天预报:',data.daily);}).catch(error=>{console.error(error.message);});九、缓存策略设计
天气数据有实时性要求,但并不代表每一次页面访问都必须重新请求接口。合理缓存可以减少接口调用次数,也能提升页面响应速度。
推荐缓存策略:
| 数据类型 | 建议缓存时间 | 原因 |
|---|---|---|
| 实时天气 | 5-10 分钟 | 变化较快,但不需要秒级刷新 |
| 分钟级降水 | 2-5 分钟 | 对出行提醒较敏感 |
| 逐小时预报 | 10-30 分钟 | 更新频率适中 |
| 15 天预报 | 1-3 小时 | 变化频率相对较低 |
| 气象预警 | 5-10 分钟 | 需要较及时更新 |
Redis 缓存示例:
asyncfunctiongetWeatherWithCache(city,type='all'){constcacheKey=`weather:${type}:${city}`;constcached=awaitredis.get(cacheKey);if(cached){returnJSON.parse(cached);}constdata=awaitweatherService.queryByCity(city,type);letttl=600;if(type==='minutely'){ttl=180;}if(type==='daily'){ttl=3600;}awaitredis.set(cacheKey,JSON.stringify(data),'EX',ttl);returndata;}如果是高并发首页场景,建议优先读取缓存,再异步刷新数据,避免大量用户同时触发接口请求。
十、异常处理设计
天气接口在实际使用中可能出现这些异常:
- 城市名称为空
- 城市名称不存在
- 查询参数错误
- API Key 未配置
- API Key 无效
- 请求超时
- 接口返回异常
- 数据源暂时不可用
- 请求频率过高
后端建议统一转换错误信息,不要把原始异常直接暴露给前端用户。
示例:
functionformatWeatherError(error){constmessage=error.message||'';if(message.includes('城市')){return'请输入正确的城市名称';}if(message.includes('超时')){return'天气查询超时,请稍后再试';}if(message.includes('密钥')){return'天气服务暂时不可用';}return'天气查询失败,请稍后再试';}路由中使用:
router.get('/api/weather',async(req,res)=>{try{constdata=awaitgetWeatherWithCache(req.query.city,req.query.type);res.json({success:true,data});}catch(error){res.status(400).json({success:false,message:formatWeatherError(error)});}});前端展示时也要避免空白页面:
try{constweather=awaitloadWeather('北京');renderWeather(weather);}catch(error){showToast(error.message||'天气数据加载失败');}十一、接口安全建议
天气接口通常需要使用 API Key 鉴权。实际项目中要注意以下几点:
- API Key 只保存在后端。
- 不要把 API Key 写到前端代码里。
- 不要把密钥提交到 Git 仓库。
- 不要在日志中打印完整密钥。
- 对前端查询接口增加限流。
- 对异常城市名和高频请求做风控。
- 生产环境和测试环境使用不同密钥。
错误写法:
// 不推荐:不要在前端暴露接口密钥constapiKey='your_api_key';推荐写法:
APIZERO_API_KEY=your_api_keyNode.js 中读取:
constapiKey=process.env.APIZERO_API_KEY;如果项目需要部署到服务器,可以使用环境变量、Docker Secret、Kubernetes Secret 或云厂商密钥管理服务保存密钥。
十二、数据库表设计参考
如果项目只是做普通天气查询,不一定需要把数据落库。如果需要做多城市天气看板、历史趋势分析或预警记录,可以设计天气数据表。
1. 城市天气表
CREATETABLEcity_weather(idBIGINTPRIMARYKEYAUTO_INCREMENT,city_nameVARCHAR(64)NOTNULL,weatherVARCHAR(64),temperatureDECIMAL(5,2),humidityDECIMAL(5,2),wind_directionVARCHAR(32),wind_speedDECIMAL(6,2),aqiINT,report_timeDATETIME,created_atDATETIMENOTNULL,updated_atDATETIMENOTNULL,INDEXidx_city_name(city_name),INDEXidx_report_time(report_time));2. 气象预警表
CREATETABLEweather_alert(idBIGINTPRIMARYKEYAUTO_INCREMENT,city_nameVARCHAR(64)NOTNULL,titleVARCHAR(128),levelVARCHAR(32),descriptionTEXT,publish_timeDATETIME,created_atDATETIMENOTNULL,INDEXidx_city_name(city_name),INDEXidx_publish_time(publish_time));这种设计适合用于后台看板、预警记录和统计分析。
十三、项目落地建议
1. 首页只展示核心天气
首页通常只需要展示:
城市 当前温度 天气现象 空气质量 今日最高温 今日最低温不要在首页加载过多数据,避免页面变慢。
2. 详情页展示完整天气数据
天气详情页可以展示:
实时天气 分钟级降水 逐小时预报 15 天预报 生活指数 气象预警这样既保证首页轻量,也能满足用户深度查看需求。
3. 高并发场景必须使用缓存
如果多个用户频繁查询同一个城市,例如北京、上海、广州、深圳,建议使用 Redis 缓存。热门城市可以提前定时刷新,用户访问时直接读取缓存。
4. 异常天气可以触发业务提醒
对于物流、校园、社区、出行类项目,可以把气象预警和业务通知结合起来。
例如:
暴雨预警 → 提醒用户提前出门 大风预警 → 提醒骑行用户注意安全 高温预警 → 提醒配送人员防暑 低温预警 → 提醒用户注意保暖这样天气数据就不只是展示信息,而是参与业务流程。
十四、常见问题
1. 天气 API 适合哪些项目?
适合出行应用、旅游系统、物流配送、智慧城市、农业系统、校园应用、社区服务、小程序工具和数据看板。
2. 前端可以直接调用天气接口吗?
不建议。涉及 API Key 的接口应该由后端调用,前端只请求自己的业务接口,避免密钥泄露。
3. 实时天气需要每次都请求接口吗?
不需要。实时天气可以缓存 5-10 分钟。对于热门城市,可以使用定时任务提前刷新缓存。
4. 15 天预报适合多久缓存?
15 天预报变化频率相对较低,一般可以缓存 1-3 小时。具体时间可以根据业务实时性要求调整。
5. 查询失败时应该怎么处理?
后端应统一返回友好的错误提示,例如“天气查询失败,请稍后再试”。同时在服务端日志中记录完整错误,方便排查问题。
6. 天气数据需要入库吗?
普通查询工具可以不入库。如果需要做历史趋势、多城市看板、预警记录或业务分析,可以保存关键天气数据。
十五、总结
天气 API 是很多业务系统中非常实用的数据能力。通过统一的天气查询接口,开发者可以快速实现实时天气、分钟级降水、逐小时预报、15 天预报和气象预警等功能。
在实际项目中,推荐采用以下接入方式:
前端输入城市名 ↓ 后端封装天气查询服务 ↓ 调用天气查询接口 ↓ 统一格式化返回结构 ↓ Redis 缓存天气数据 ↓ 前端展示天气卡片、预报列表和预警信息这种方案既能保证接口安全,也方便后续扩展缓存、限流、日志、预警通知和数据分析能力。
对于 Web 后台、小程序、App 后端、数据看板和企业内部系统来说,把天气查询能力封装成独立服务模块,是一种更清晰、稳定、可维护的实现方式。
参考链接:
https://apizero.cn/tools/weather https://v1.apizero.cn/api/weather