天气 API 接入实战:基于 ApiZero 实现实时天气、分钟级降水和 15 天预报查询

在很多业务系统中,天气数据并不是一个"装饰功能",而是会直接影响用户体验和业务决策的数据能力。

例如,出行类应用需要展示实时天气和降水趋势;旅游系统需要提示景区天气和气象预警;物流系统需要关注暴雨、大风、低温等异常天气对配送的影响;农业、校园、社区、智慧城市类项目,也经常需要接入天气预报、空气质量、生活指数等数据。

如果开发者从零开始对接多个气象数据源,不仅要处理不同接口格式,还要考虑城市定位、实时天气、小时预报、未来多日预报、气象预警等多类数据的整合问题。使用统一的天气查询 API,可以明显降低开发和维护成本。

本文以 ApiZero 天气查询接口为例,整理一套适合实际项目落地的天气 API 接入方案,包含接口能力说明、请求方式、后端封装、前端展示、缓存策略、异常处理和安全建议。

接口地址:

text 复制代码
https://v1.apizero.cn/api/weather

工具页面:

text 复制代码
https://apizero.cn/tools/weather

一、为什么项目中需要天气查询接口

天气查询接口常用于这些场景:

使用场景 典型需求
出行应用 展示实时天气、降水概率、未来天气趋势
旅游系统 根据天气情况提示用户出行建议
物流配送 根据暴雨、大风、高温等天气调整配送策略
智慧城市 展示城市气象、空气质量、预警信息
农业系统 结合降水、温度、湿度辅助种植管理
校园/社区应用 展示本地天气和生活指数
数据看板 汇总多城市天气数据,辅助运营分析

天气接口的核心价值不只是"查天气",而是把天气数据嵌入业务流程中,让系统可以根据实时气象变化做出更合理的展示、提醒和决策。

二、接口能力概览

ApiZero 天气查询工具支持实时天气、分钟级降水、逐小时预报、15 天预报和气象预警等能力。对于大多数 Web 项目、小程序、App 后端和数据看板来说,这些能力基本可以覆盖常见天气查询需求。

能力 说明 常见用途
实时天气 查询当前温度、湿度、天气现象、风速等 首页天气卡片、城市天气查询
分钟级降水 查询未来短时间内降水趋势 出行提醒、骑行提醒、配送预警
逐小时预报 查询未来多个小时的天气变化 分时天气曲线、活动安排
15 天预报 查询未来多日天气趋势 旅游计划、出行计划
气象预警 获取异常天气提示 应急提醒、风险提示
城市查询 按城市名或区域名查询天气 城市天气搜索、本地生活工具

建议开发者不要把天气接口只当成简单查询接口,而是按照"数据服务模块"来设计。这样后续扩展前端页面、缓存策略、预警通知和数据分析会更方便。

三、接口接入前的准备工作

接入天气接口前,需要先明确以下几个问题:

  1. 查询入口是城市名,还是经纬度?
  2. 前端是否需要展示实时天气?
  3. 是否需要展示未来 15 天预报?
  4. 是否需要分钟级降水提醒?
  5. 是否需要气象预警?
  6. 是否要把天气结果缓存到 Redis?
  7. API Key 是否只在后端保存?
  8. 异常时前端应该显示什么提示?

推荐的基础接入链路如下:

text 复制代码
用户输入城市名
        ↓
前端提交查询请求
        ↓
后端调用天气接口
        ↓
后端统一格式化天气数据
        ↓
前端展示实时天气、预报和预警

这种方式可以避免前端直接暴露密钥,也能方便后端统一做缓存、限流、日志和异常处理。

四、接口请求方式设计

天气接口地址如下:

text 复制代码
https://v1.apizero.cn/api/weather

实际项目中,建议通过后端调用接口,而不是让前端直接请求第三方接口。

1. curl 请求示例

以下示例用于说明常见调用方式,具体参数名称以实际接口文档为准。

bash 复制代码
curl -X GET "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. 安装依赖

bash 复制代码
npm install axios

2. 基础调用代码

javascript 复制代码
const axios = require('axios');

async function queryWeather(city) {
  if (!city || !city.trim()) {
    throw new Error('城市名称不能为空');
  }

  const apiKey = process.env.APIZERO_API_KEY;

  if (!apiKey) {
    throw new Error('缺少 APIZERO_API_KEY 环境变量');
  }

  const response = await axios.get('https://v1.apizero.cn/api/weather', {
    params: {
      city,
      type: 'all'
    },
    headers: {
      Authorization: `Bearer ${apiKey}`
    },
    timeout: 8000
  });

  return response.data;
}

queryWeather('北京')
  .then(data => {
    console.log('天气数据:', data);
  })
  .catch(error => {
    console.error('天气查询失败:', error.message);
  });

这段代码只适合演示。实际项目中,建议继续封装服务层,避免业务代码直接散落调用第三方接口。

六、封装天气查询服务

推荐在后端创建一个独立的天气服务类,例如 WeatherService

1. 服务封装示例

javascript 复制代码
const axios = require('axios');

class WeatherService {
  constructor() {
    this.baseURL = 'https://v1.apizero.cn/api/weather';
    this.apiKey = process.env.APIZERO_API_KEY;
  }

  async queryByCity(city, type = 'all') {
    this.validateCity(city);
    this.validateApiKey();

    try {
      const response = await axios.get(this.baseURL, {
        params: {
          city,
          type
        },
        headers: {
          Authorization: `Bearer ${this.apiKey}`
        },
        timeout: 8000
      });

      return this.normalize(response.data);
    } catch (error) {
      throw this.handleError(error);
    }
  }

  validateCity(city) {
    if (!city || !city.trim()) {
      throw new Error('城市名称不能为空');
    }
  }

  validateApiKey() {
    if (!this.apiKey) {
      throw new Error('接口密钥未配置');
    }
  }

  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') {
      return new Error('天气接口请求超时');
    }

    if (error.response) {
      return new Error(`天气接口异常:${error.response.status}`);
    }

    return new Error('天气接口请求失败');
  }
}

module.exports = WeatherService;

2. 路由接口示例

javascript 复制代码
const express = require('express');
const WeatherService = require('./WeatherService');

const router = express.Router();
const weatherService = new WeatherService();

router.get('/api/weather', async (req, res) => {
  const { city, type } = req.query;

  try {
    const data = await weatherService.queryByCity(city, type);

    res.json({
      success: true,
      data
    });
  } catch (error) {
    res.status(400).json({
      success: false,
      message: error.message
    });
  }
});

module.exports = router;

通过这种方式,前端只请求自己的业务后端:

text 复制代码
/api/weather?city=北京&type=all

真正的接口密钥只保存在服务端,安全性更高。

七、推荐返回结构设计

不同天气接口的原始返回结构可能比较复杂。为了让前端更容易使用,建议后端统一转换成稳定的数据格式。

示例结构:

json 复制代码
{
  "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": "预计未来短时间内可能出现雷电天气"
    }
  ]
}

前端拿到这种结构后,可以直接拆成多个模块展示:

text 复制代码
实时天气卡片
分钟级降水提示
逐小时天气折线图
15 天天气列表
气象预警卡片

八、前端展示示例

1. 天气卡片 HTML

html 复制代码
<div class="weather-card">
  <div class="city">北京</div>
  <div class="temperature">26℃</div>
  <div class="weather">多云</div>
  <div class="meta">
    <span>湿度:52%</span>
    <span>空气质量:48</span>
  </div>
</div>

2. 天气卡片 CSS

css 复制代码
.weather-card {
  width: 320px;
  padding: 20px;
  border-radius: 12px;
  background: linear-gradient(135deg, #eef6ff, #ffffff);
  box-shadow: 0 8px 24px rgba(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. 前端请求示例

javascript 复制代码
async function loadWeather(city) {
  const response = await fetch(`/api/weather?city=${encodeURIComponent(city)}&type=all`);

  const result = await response.json();

  if (!result.success) {
    throw new Error(result.message || '天气查询失败');
  }

  return result.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 缓存示例:

javascript 复制代码
async function getWeatherWithCache(city, type = 'all') {
  const cacheKey = `weather:${type}:${city}`;

  const cached = await redis.get(cacheKey);
  if (cached) {
    return JSON.parse(cached);
  }

  const data = await weatherService.queryByCity(city, type);

  let ttl = 600;

  if (type === 'minutely') {
    ttl = 180;
  }

  if (type === 'daily') {
    ttl = 3600;
  }

  await redis.set(cacheKey, JSON.stringify(data), 'EX', ttl);

  return data;
}

如果是高并发首页场景,建议优先读取缓存,再异步刷新数据,避免大量用户同时触发接口请求。

十、异常处理设计

天气接口在实际使用中可能出现这些异常:

  • 城市名称为空
  • 城市名称不存在
  • 查询参数错误
  • API Key 未配置
  • API Key 无效
  • 请求超时
  • 接口返回异常
  • 数据源暂时不可用
  • 请求频率过高

后端建议统一转换错误信息,不要把原始异常直接暴露给前端用户。

示例:

javascript 复制代码
function formatWeatherError(error) {
  const message = error.message || '';

  if (message.includes('城市')) {
    return '请输入正确的城市名称';
  }

  if (message.includes('超时')) {
    return '天气查询超时,请稍后再试';
  }

  if (message.includes('密钥')) {
    return '天气服务暂时不可用';
  }

  return '天气查询失败,请稍后再试';
}

路由中使用:

javascript 复制代码
router.get('/api/weather', async (req, res) => {
  try {
    const data = await getWeatherWithCache(req.query.city, req.query.type);

    res.json({
      success: true,
      data
    });
  } catch (error) {
    res.status(400).json({
      success: false,
      message: formatWeatherError(error)
    });
  }
});

前端展示时也要避免空白页面:

javascript 复制代码
try {
  const weather = await loadWeather('北京');
  renderWeather(weather);
} catch (error) {
  showToast(error.message || '天气数据加载失败');
}

十一、接口安全建议

天气接口通常需要使用 API Key 鉴权。实际项目中要注意以下几点:

  1. API Key 只保存在后端。
  2. 不要把 API Key 写到前端代码里。
  3. 不要把密钥提交到 Git 仓库。
  4. 不要在日志中打印完整密钥。
  5. 对前端查询接口增加限流。
  6. 对异常城市名和高频请求做风控。
  7. 生产环境和测试环境使用不同密钥。

错误写法:

javascript 复制代码
// 不推荐:不要在前端暴露接口密钥
const apiKey = 'your_api_key';

推荐写法:

bash 复制代码
APIZERO_API_KEY=your_api_key

Node.js 中读取:

javascript 复制代码
const apiKey = process.env.APIZERO_API_KEY;

如果项目需要部署到服务器,可以使用环境变量、Docker Secret、Kubernetes Secret 或云厂商密钥管理服务保存密钥。

十二、数据库表设计参考

如果项目只是做普通天气查询,不一定需要把数据落库。如果需要做多城市天气看板、历史趋势分析或预警记录,可以设计天气数据表。

1. 城市天气表

sql 复制代码
CREATE TABLE city_weather (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  city_name VARCHAR(64) NOT NULL,
  weather VARCHAR(64),
  temperature DECIMAL(5,2),
  humidity DECIMAL(5,2),
  wind_direction VARCHAR(32),
  wind_speed DECIMAL(6,2),
  aqi INT,
  report_time DATETIME,
  created_at DATETIME NOT NULL,
  updated_at DATETIME NOT NULL,
  INDEX idx_city_name (city_name),
  INDEX idx_report_time (report_time)
);

2. 气象预警表

sql 复制代码
CREATE TABLE weather_alert (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  city_name VARCHAR(64) NOT NULL,
  title VARCHAR(128),
  level VARCHAR(32),
  description TEXT,
  publish_time DATETIME,
  created_at DATETIME NOT NULL,
  INDEX idx_city_name (city_name),
  INDEX idx_publish_time (publish_time)
);

这种设计适合用于后台看板、预警记录和统计分析。

十三、项目落地建议

1. 首页只展示核心天气

首页通常只需要展示:

text 复制代码
城市
当前温度
天气现象
空气质量
今日最高温
今日最低温

不要在首页加载过多数据,避免页面变慢。

2. 详情页展示完整天气数据

天气详情页可以展示:

text 复制代码
实时天气
分钟级降水
逐小时预报
15 天预报
生活指数
气象预警

这样既保证首页轻量,也能满足用户深度查看需求。

3. 高并发场景必须使用缓存

如果多个用户频繁查询同一个城市,例如北京、上海、广州、深圳,建议使用 Redis 缓存。热门城市可以提前定时刷新,用户访问时直接读取缓存。

4. 异常天气可以触发业务提醒

对于物流、校园、社区、出行类项目,可以把气象预警和业务通知结合起来。

例如:

text 复制代码
暴雨预警 → 提醒用户提前出门
大风预警 → 提醒骑行用户注意安全
高温预警 → 提醒配送人员防暑
低温预警 → 提醒用户注意保暖

这样天气数据就不只是展示信息,而是参与业务流程。

十四、常见问题

1. 天气 API 适合哪些项目?

适合出行应用、旅游系统、物流配送、智慧城市、农业系统、校园应用、社区服务、小程序工具和数据看板。

2. 前端可以直接调用天气接口吗?

不建议。涉及 API Key 的接口应该由后端调用,前端只请求自己的业务接口,避免密钥泄露。

3. 实时天气需要每次都请求接口吗?

不需要。实时天气可以缓存 5-10 分钟。对于热门城市,可以使用定时任务提前刷新缓存。

4. 15 天预报适合多久缓存?

15 天预报变化频率相对较低,一般可以缓存 1-3 小时。具体时间可以根据业务实时性要求调整。

5. 查询失败时应该怎么处理?

后端应统一返回友好的错误提示,例如"天气查询失败,请稍后再试"。同时在服务端日志中记录完整错误,方便排查问题。

6. 天气数据需要入库吗?

普通查询工具可以不入库。如果需要做历史趋势、多城市看板、预警记录或业务分析,可以保存关键天气数据。

十五、总结

天气 API 是很多业务系统中非常实用的数据能力。通过统一的天气查询接口,开发者可以快速实现实时天气、分钟级降水、逐小时预报、15 天预报和气象预警等功能。

在实际项目中,推荐采用以下接入方式:

text 复制代码
前端输入城市名
        ↓
后端封装天气查询服务
        ↓
调用天气查询接口
        ↓
统一格式化返回结构
        ↓
Redis 缓存天气数据
        ↓
前端展示天气卡片、预报列表和预警信息

这种方案既能保证接口安全,也方便后续扩展缓存、限流、日志、预警通知和数据分析能力。

对于 Web 后台、小程序、App 后端、数据看板和企业内部系统来说,把天气查询能力封装成独立服务模块,是一种更清晰、稳定、可维护的实现方式。

参考链接:

text 复制代码
https://apizero.cn/tools/weather
https://v1.apizero.cn/api/weather
相关推荐
自动跟随3 小时前
UWB自动跟随技术全栈解析:从定位算法到“位控一体化“
java·网络·人工智能
喜欢打篮球的普通人3 小时前
LLVM 后端流程与关键数据结构:从 IR 到机器码的入门笔记
java·数据结构·笔记
弹简特3 小时前
【Java项目-轻聊】07-实现主页面模块
java·开发语言
wuminyu3 小时前
Java锁机制之轻量级锁判断与尝试逻辑源码剖析
java·linux·c语言·jvm·c++
Misnearch3 小时前
1、数组/字符串
java·数据结构·算法
☆cwlulu3 小时前
Linux系统调用与C库I/O的底层奥秘
java·spring boot·spring
pe7er3 小时前
软件设计不要“既要又要”
前端·后端·架构
柏舟飞流3 小时前
Spring Boot 深入实践指南:从入门到工程化落地
spring boot·后端·firefox
于先生吖3 小时前
前后端分离人事招聘项目,校招宣讲预约+社招双向撮合功能架构设计教程
java·开发语言·uni-app