4. RESTful API 设计原则:资源命名规范、URL设计、版本控制、无状态特性、使用JSON作为数据交换格式
在物联网采集平台中,HTTP API 是设备与平台、平台与上层应用之间的核心通信契约。遵循 RESTful 设计原则能够确保 API 的可读性、可维护性和可扩展性。本章将围绕资源命名、URL 结构、版本控制、无状态约束以及数据格式五个关键维度展开,为后续的接口实现奠定规范基础。
4.1 资源命名规范
RESTful 架构将一切视为“资源”(Resource),每个资源通过唯一的 URI 标识。命名规范直接影响 API 的易用性与一致性。
| 规范项 | 推荐做法 | 反例 |
|---|---|---|
| 名词复数 | 使用复数名词表示资源集合,如 /devices、/sensors |
/getDevice、/device(单数) |
| 小写字母 | 全部小写,避免大小写歧义 | /DeviceList、/SensorsData |
| 连字符分隔 | 使用连字符 - 分隔多词资源名 |
/temperature_sensor(下划线)、/temperatureSensor(驼峰) |
| 避免动词 | 用 HTTP 方法表达动作,资源名只表达实体 | /createDevice、/deleteSensor |
| 层级关系 | 通过路径嵌套表达从属关系 | /devices?id=123&type=sensor(扁平化) |
最佳实践:物联网场景中常见资源包括
/devices、/gateways、/sensors、/telemetry、/alarms。保持命名与业务术语一致,避免引入技术实现细节(如 /getLatestData)。
4.2 URL 设计模式
URL 是资源的地址,设计时应兼顾可读性与查询效率。以下为物联网采集平台的典型 URL 模式:
# 资源集合
GET /devices # 获取设备列表
POST /devices # 创建设备
# 单个资源
GET /devices/{deviceId} # 获取指定设备
PUT /devices/{deviceId} # 更新设备
DELETE /devices/{deviceId} # 删除设备
# 子资源(从属关系)
GET /devices/{deviceId}/sensors # 获取某设备下的传感器列表
POST /devices/{deviceId}/sensors # 为该设备添加传感器
# 子资源实例
GET /devices/{deviceId}/sensors/{sensorId} # 获取指定传感器
GET /devices/{deviceId}/sensors/{sensorId}/telemetry # 获取传感器遥测数据
# 查询参数(过滤、排序、分页)
GET /devices?status=active&page=1&size=20
GET /telemetry?from=2025-01-01&to=2025-01-31&sort=timestamp,desc
关键原则:路径参数(Path Parameter)用于定位资源身份,查询参数(Query Parameter)用于过滤、排序和分页。不要将动作或操作编码在 URL 中,而是通过 HTTP 方法(GET/POST/PUT/DELETE)表达语义。
4.3 版本控制
API 版本控制是保障向后兼容性的核心手段。物联网平台通常面临设备固件升级滞后、多版本客户端共存等挑战,合理的版本策略至关重要。
| 版本策略 | 实现方式 | 示例 | 适用场景 |
|---|---|---|---|
| URL 路径版本 | 将版本号嵌入 URL 路径 | /api/v1/devices |
最常用,显式、易于路由 |
| 请求头版本 | 通过自定义 Header 传递版本 | Accept: application/vnd.iot.v2+json |
需要更干净的 URL |
| 查询参数版本 | 通过 ?version=1 指定 |
/devices?version=1 |
临时过渡,不推荐长期使用 |
版本管理建议:推荐使用 URL 路径版本(如
/api/v1/、/api/v2/),因为它在日志、缓存、API 网关路由中最为直观。版本号应为主版本号,向后兼容的次要变更不应升级版本。废弃旧版本时,至少提前一个发布周期通知客户端,并保留 6 个月以上的迁移窗口。
4.4 无状态特性
RESTful API 要求服务器不保存客户端请求之间的任何上下文(Session)。每个请求必须包含服务器处理该请求所需的全部信息。
- 认证信息:每个请求携带 Token 或 API Key,不依赖服务器 Session。
- 上下文数据:分页、排序、过滤参数全部通过请求参数传递。
- 幂等性:同一请求重复执行应产生相同结果(GET、PUT、DELETE 天然幂等)。
- 水平扩展:无状态设计使得任意服务器实例均可处理任意请求,无需 Session 同步。
物联网场景价值:设备上报数据时,每个 HTTP 请求独立携带设备 ID、时间戳、签名等信息,服务器无需维护设备连接状态。这大幅降低了网关和微服务的复杂度,支持弹性伸缩。
4.5 使用 JSON 作为数据交换格式
JSON(JavaScript Object Notation)因其轻量、易读、跨语言支持广泛,已成为 RESTful API 的事实标准数据格式。物联网平台中,JSON 用于设备上报、指令下发、配置同步等所有数据交互。
以下为物联网采集平台中典型的 JSON 数据模型示例:
// 设备上报遥测数据
POST /api/v1/devices/{deviceId}/telemetry
Content-Type: application/json
{
"deviceId": "sensor-001",
"timestamp": "2025-03-21T14:30:00Z",
"measurements": {
"temperature": 23.5,
"humidity": 68.2,
"pressure": 1013.25
},
"metadata": {
"firmwareVersion": "2.1.0",
"batteryLevel": 85
}
}
// 平台下发指令
POST /api/v1/devices/{deviceId}/commands
Content-Type: application/json
{
"commandId": "cmd-20250321-001",
"type": "setThreshold",
"parameters": {
"sensor": "temperature",
"min": 10.0,
"max": 40.0
},
"expiry": "2025-03-21T15:00:00Z"
}
| JSON 使用规范 | 说明 |
|---|---|
| 字段命名 | 使用小驼峰(camelCase),如 deviceId、firmwareVersion |
| 时间格式 | 统一使用 ISO 8601 格式,如 2025-03-21T14:30:00Z |
| 数值精度 | 浮点数保留合理小数位,避免精度丢失 |
| 空值处理 | 使用 null 表示缺失,避免省略字段 |
| Content-Type | 请求头必须设置 Content-Type: application/json |
| 响应格式 | 统一封装为 { "code": 200, "message": "success", "data": {...} } |
4.6 综合设计示例
以下为一个完整的物联网采集平台 API 端点设计清单,综合应用上述五项原则:
| HTTP 方法 | URL 路径 | 功能描述 | 请求体格式 |
|---|---|---|---|
| GET | /api/v1/devices |
获取设备列表(支持分页、状态过滤) | — |
| POST | /api/v1/devices |
注册新设备 | JSON |
| GET | /api/v1/devices/{deviceId} |
获取单个设备详情 | — |
| PUT | /api/v1/devices/{deviceId} |
更新设备配置 | JSON |
| DELETE | /api/v1/devices/{deviceId} |
注销设备 | — |
| GET | /api/v1/devices/{deviceId}/telemetry |
获取设备遥测历史(支持时间范围) | — |
| POST | /api/v1/devices/{deviceId}/telemetry |
设备上报遥测数据 | JSON |
| POST | /api/v1/devices/{deviceId}/commands |
下发控制指令 | JSON |
设计检查清单:每个端点是否使用名词复数?是否通过 HTTP 方法表达语义?是否包含版本号?是否无状态(Token 在 Header 中)?请求和响应是否使用 JSON?通过此清单快速验证 API 设计的 RESTful 合规性。