4、HTTP基础回顾:HTTP/HTTPS协议、请求方法(GET/POST/PUT/DELETE)、状态码含义、RESTful API设计原则
好,咱们进入第四讲。说实话,很多做LoRaWAN应用开发的朋友,一开始都栽在HTTP上。不是协议多难,而是细节太多。我当年刚接手第一个物联网项目时,就因为搞混了PUT和PATCH,让设备数据同步乱了整整两天。嗯,从那以后,我养成了一个习惯——每次写接口前,先把HTTP基础过一遍。
这一节,咱们就把HTTP/HTTPS、请求方法、状态码、RESTful设计原则,一次性讲透。你想想看,后面我们要写的LoRaWAN应用服务器接口,本质上就是一套RESTful API。基础不牢,后面写代码就是空中楼阁。
4.1 HTTP与HTTPS:不只是多了一个S
HTTP,全称超文本传输协议。说白了,就是客户端和服务器之间约定好的一种对话方式。你发请求,我回响应,就这么简单。
但HTTP有个致命问题——明文传输。我在项目中曾经用Wireshark抓包看过,一个POST请求里,用户名、密码、设备EUI,全裸奔在网络上。这要是被中间人截获,后果不堪设想。
HTTPS就是在HTTP外面套了一层SSL/TLS加密。我个人习惯,凡是涉及设备数据、用户信息的接口,一律上HTTPS。别图省事,现在Let's Encrypt免费证书很好申请,没必要裸奔。
| 对比项 | HTTP | HTTPS |
|---|---|---|
| 安全性 | 明文传输,无加密 | SSL/TLS加密,防窃听 |
| 默认端口 | 80 | 443 |
| 证书 | 不需要 | 需要CA证书 |
| 性能 | 较快 | 略慢(握手开销) |
| 推荐场景 | 内网调试、非敏感数据 | 生产环境、用户数据 |
4.2 请求方法:GET/POST/PUT/DELETE
HTTP定义了多种请求方法,但咱们做LoRaWAN应用服务器,最常用的就四个:GET、POST、PUT、DELETE。说白了,就是增删改查的四个动作。
4.2.1 GET:获取资源
GET请求用来从服务器获取数据。它应该是幂等的——你调一次和调一百次,结果应该一样。我在项目中见过有人用GET请求去修改设备状态,这是典型的错误用法。
// 正确:获取设备信息
GET /api/devices/123456
// 错误:用GET修改数据
GET /api/devices/123456?status=offline // 别这么干!
4.2.2 POST:创建资源
POST用来在服务器上创建新资源。每次调用POST,通常都会产生一个新的资源ID。比如注册一个新设备:
POST /api/devices
Content-Type: application/json
{
"devEUI": "AABBCCDDEEFF0011",
"appKey": "1234567890ABCDEF1234567890ABCDEF",
"name": "温湿度传感器-01"
}
注意,POST不是幂等的。你发两次同样的POST请求,服务器上会创建两个资源。我刚开始做接口时,就因为没处理好重复提交,数据库里多了好几条重复的设备记录。
4.2.3 PUT:更新资源
PUT用来完整替换一个资源。它要求客户端提供资源的完整信息。说白了,就是你把整个资源的新版本发给服务器,服务器用你给的内容完全覆盖旧的。
PUT /api/devices/AABBCCDDEEFF0011
Content-Type: application/json
{
"devEUI": "AABBCCDDEEFF0011",
"name": "温湿度传感器-01(已更新)",
"location": "仓库A区"
}
4.2.4 DELETE:删除资源
DELETE用来删除指定资源。它也是幂等的——你删一次和删十次,结果都是资源不存在了。
DELETE /api/devices/AABBCCDDEEFF0011
这里有个细节:DELETE请求通常没有请求体。如果你需要在删除时传一些参数(比如删除原因),建议用查询参数或者干脆改用POST。
4.3 状态码含义:服务器在说什么?
状态码是服务器对客户端请求的回应。三位的数字,背后藏着很多信息。我刚开始看状态码时,只记得200和404,后来被坑了几次,才老老实实把常用的都记住了。
| 状态码 | 含义 | 说明 |
|---|---|---|
| 200 OK | 请求成功 | GET、PUT、DELETE成功时常用 |
| 201 Created | 创建成功 | POST创建资源成功后返回 |
| 204 No Content | 成功但无返回体 | DELETE成功时常用 |
| 400 Bad Request | 请求格式错误 | 参数缺失、JSON格式错误等 |
| 401 Unauthorized | 未认证 | 缺少Token或Token无效 |
| 403 Forbidden | 无权限 | 认证通过但权限不足 |
| 404 Not Found | 资源不存在 | URL路径错误或资源已删除 |
| 409 Conflict | 资源冲突 | 重复创建、数据版本冲突等 |
| 429 Too Many Requests | 请求频率过高 | 限流触发 |
| 500 Internal Server Error | 服务器内部错误 | 代码异常、数据库连接失败等 |
4.4 RESTful API设计原则
RESTful,全称Representational State Transfer。说白了,就是一种API的设计风格。它不是标准,而是一套约定。你想想看,如果每个公司都按自己的风格设计API,那前端得适配多少种接口格式?
我个人总结了几条核心原则,你在设计LoRaWAN应用服务器接口时,照着做就行:
4.4.1 资源路径用名词,不用动词
好的RESTful API,路径里只有名词,没有动词。因为HTTP方法已经表达了动作。
// 好的设计
GET /api/devices // 获取设备列表
POST /api/devices // 创建设备
GET /api/devices/{devEUI} // 获取单个设备
PUT /api/devices/{devEUI} // 更新设备
DELETE /api/devices/{devEUI} // 删除设备
// 不好的设计
GET /api/getDevices // 动词出现在路径中
POST /api/createDevice // 同上
POST /api/deleteDevice // 应该用DELETE方法
4.4.2 使用复数名词
资源路径统一用复数形式。比如 /api/devices 而不是 /api/device。这看起来是小事,但统一风格后,团队协作会顺畅很多。
4.4.3 版本控制
API一定要有版本号。我见过一个项目,API改了三次,前端还在调旧接口,结果数据全乱了。加上版本号,新旧接口可以共存,平滑过渡。
/api/v1/devices
/api/v2/devices
4.4.4 使用合适的HTTP方法
这个前面已经讲过了,再强调一次:GET查、POST增、PUT全量更新、DELETE删。别混用,别偷懒。
4.4.5 统一响应格式
所有接口的响应格式要统一。我个人习惯用这种结构:
{
"code": 200,
"message": "success",
"data": {
// 实际数据
}
}
// 错误时
{
"code": 400,
"message": "参数错误:devEUI不能为空",
"data": null
}
4.5 实战:一个LoRaWAN设备管理API示例
说了这么多理论,咱们来点实际的。假设我们要设计一个LoRaWAN设备管理的API,按照RESTful风格,大概长这样:
// 1. 获取设备列表
GET /api/v1/devices?page=1&size=20
响应:
{
"code": 200,
"message": "success",
"data": {
"total": 150,
"page": 1,
"size": 20,
"items": [
{
"devEUI": "AABBCCDDEEFF0011",
"name": "温湿度传感器-01",
"status": "online",
"lastSeen": "2024-01-15T10:30:00Z"
}
]
}
}
// 2. 注册新设备
POST /api/v1/devices
请求体:
{
"devEUI": "AABBCCDDEEFF0022",
"appKey": "1234567890ABCDEF1234567890ABCDEF",
"name": "门磁传感器-02"
}
响应(201 Created):
{
"code": 201,
"message": "设备注册成功",
"data": {
"devEUI": "AABBCCDDEEFF0022",
"name": "门磁传感器-02",
"status": "inactive"
}
}
// 3. 更新设备信息
PUT /api/v1/devices/AABBCCDDEEFF0022
请求体:
{
"devEUI": "AABBCCDDEEFF0022",
"name": "门磁传感器-02(已迁移)",
"location": "仓库B区"
}
响应:
{
"code": 200,
"message": "更新成功",
"data": {
"devEUI": "AABBCCDDEEFF0022",
"name": "门磁传感器-02(已迁移)",
"location": "仓库B区"
}
}
// 4. 删除设备
DELETE /api/v1/devices/AABBCCDDEEFF0022
响应(204 No Content,无响应体)
你看,整个设计清晰明了。前端拿到这个API文档,不用问后端就能直接开干。这就是RESTful的魅力。
好,这一讲就到这里。有什么问题,咱们在课程群里聊。记住,写接口前,先把HTTP基础过一遍——这是我踩过坑后最想对你说的话。