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证书
性能 较快 略慢(握手开销)
推荐场景 内网调试、非敏感数据 生产环境、用户数据
我的经验:开发调试阶段可以用HTTP,但上线前一定要切HTTPS。我曾经见过一个项目,上线半年才发现设备上报的密钥是明文传输的——那感觉,就像家里门锁是纸糊的。

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区"
}
避坑指南:我曾经犯过一个错——用PUT做部分更新。PUT要求传完整资源,如果你只传了name字段,服务器可能会把其他字段置空。部分更新应该用PATCH,但很多项目图省事,直接用POST代替。我个人建议:严格遵循语义,别混用。

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 服务器内部错误 代码异常、数据库连接失败等
重点:别所有成功都返回200,所有失败都返回500。我见过一个项目,创建资源返回200,删除资源也返回200,查询不到也返回200——前端根本不知道发生了什么。正确的做法是:创建成功用201,删除成功用204,参数错误用400,权限不足用403。这样前后端协作效率会高很多。

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
}
小技巧:响应里的code和HTTP状态码可以保持一致,也可以自定义。我建议保持一致,这样前端可以直接用HTTP状态码做判断,减少一层解析。但如果你有业务层面的错误(比如设备已离线),可以在data里加一个子状态码。

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基础是LoRaWAN应用服务器开发的基石。HTTPS保安全,请求方法定语义,状态码传信息,RESTful定风格。把这四点吃透了,后面写接口就是水到渠成的事。下一节,咱们开始动手搭建开发环境,写第一个接口。

好,这一讲就到这里。有什么问题,咱们在课程群里聊。记住,写接口前,先把HTTP基础过一遍——这是我踩过坑后最想对你说的话。