2、REST API集成基础:API认证方式、请求/响应格式、常用端点、分页与过滤

好,咱们正式开始聊集成。这一章是基础中的基础,说白了就是「怎么跟 ThingsBoard 说话」。我见过不少新手,上来就调接口,结果认证没过、分页没搞对,折腾半天数据都拿不到。咱们先把这些基本功打扎实。

2.1 API认证方式:你凭什么访问?

ThingsBoard 的 REST API 默认是无状态的,每次请求都得带上身份凭证。它支持两种认证方式,我个人习惯根据场景选。

2.1.1 JWT Token(最常用)

这是最主流的做法。你先用用户名密码换一个 token,后续所有请求都带着它。Token 有过期时间,默认好像是 24 小时,过期了就得重新获取。

获取 Token:

POST /api/auth/login
Content-Type: application/json

{
  "username": "tenant@thingsboard.org",
  "password": "your_password"
}

返回结果里有个 token 字段,把它存下来。后续请求在 Header 里加上:

X-Authorization: Bearer <你的token>
我的小经验: 我在项目中遇到过 token 过期导致定时任务中断的情况。建议写个自动刷新逻辑,比如在 token 过期前 5 分钟自动重新登录。别等到报 401 了再处理,那会儿数据可能已经丢了。

2.1.2 基本认证(简单粗暴)

直接把用户名密码用 Base64 编码塞进 Header。适合快速测试,但生产环境我基本不用——太不安全了。

Authorization: Basic base64(username:password)
注意: 基本认证每次请求都传输明文密码(虽然编码了,但很容易解码)。除非你在内网且 HTTPS 是强制开启的,否则别这么干。

2.2 请求/响应格式:统一用 JSON

ThingsBoard 的 REST API 请求体和响应体都是 JSON 格式。嗯,这里要注意一点:请求头必须设置 Content-Type: application/json,否则服务端不认。

一个典型的 POST 请求长这样:

POST /api/device
Content-Type: application/json
X-Authorization: Bearer <token>

{
  "name": "温度传感器-001",
  "type": "temperature",
  "label": "车间A区"
}

响应呢,成功一般是 200 或 201,返回创建好的对象:

{
  "id": {
    "id": "d290f1ee-6c54-4b01-90e6-d701748f0851"
  },
  "name": "温度传感器-001",
  "type": "temperature",
  "label": "车间A区",
  "createdTime": 1620000000000
}

失败的话,会返回错误码和消息。比如 400 表示参数不对,401 表示没权限,404 表示资源不存在。我曾经调试一个接口,一直返回 400,查了半天才发现是 JSON 里多了一个逗号……这种低级错误,你想想看,是不是很坑?

2.3 常用端点:先记住这几个

ThingsBoard 的 API 端点很多,但日常集成常用的就那么几个。我列个表,你照着用就行。

功能 HTTP 方法 端点 说明
获取设备列表 GET /api/tenant/devices 获取当前租户下的所有设备
获取单个设备 GET /api/device/{deviceId} 根据设备 ID 获取详情
创建设备 POST /api/device 新建一个设备
删除设备 DELETE /api/device/{deviceId} 删除指定设备
获取遥测数据 GET /api/plugins/telemetry/{entityType}/{entityId}/values/timeseries 获取设备的最新遥测值
保存遥测数据 POST /api/v1/{deviceToken}/telemetry 设备端上报数据用这个
获取告警列表 GET /api/alarm/{entityType}/{entityId} 获取某个实体的告警
重点: 遥测数据的上报路径 /api/v1/{deviceToken}/telemetry 用的是设备令牌(device token),不是 JWT。这个容易搞混,我刚开始也踩过这个坑。

2.4 分页与过滤:数据多了怎么办?

一个系统跑久了,设备成千上万,遥测数据更是海量。你总不能一次全拉回来吧?ThingsBoard 提供了标准的分页和过滤参数。

2.4.1 分页参数

所有列表接口都支持 pagepageSize 参数。注意,page 从 0 开始,不是 1。

GET /api/tenant/devices?page=0&pageSize=10

返回结果里会包含分页信息:

{
  "data": [ ... ],  // 当前页的数据
  "totalPages": 5,
  "totalElements": 50,
  "hasNext": true
}

我个人习惯每次先调一次接口拿到 totalPages,然后循环拉取所有页。但要注意,别一次性拉太多,服务器会扛不住的。

2.4.2 过滤参数

常用的过滤方式有这么几种:

  • 按名称搜索: ?textSearch=温度 —— 模糊匹配设备名称
  • 按类型过滤: ?type=temperature —— 只返回指定类型的设备
  • 按时间范围: 遥测数据接口支持 startTsendTs,单位是毫秒时间戳
  • 按排序: ?sortProperty=createdTime&sortOrder=DESC —— 按创建时间倒序

举个例子,我想查最近 1 小时内温度传感器的数据:

GET /api/plugins/telemetry/DEVICE/{deviceId}/values/timeseries
  ?keys=temperature
  &startTs=1710000000000
  &endTs=1710003600000
  &limit=100
避坑指南: 我曾经在分页时没注意 limit 参数,结果一次返回了 10000 条数据,前端直接卡死了。后来我强制限制每次最多 1000 条,不够再翻页。记住,永远不要相信客户端会主动限制数据量,服务端也要做保护。

2.5 实战小例子:用 Python 调 API

光说不练假把式。我写个简单的 Python 脚本,演示怎么获取设备列表并打印出来。

import requests
import json

BASE_URL = "http://your-thingsboard-server:8080"
USERNAME = "tenant@thingsboard.org"
PASSWORD = "your_password"

# 1. 登录获取 token
login_url = f"{BASE_URL}/api/auth/login"
login_data = {"username": USERNAME, "password": PASSWORD}
response = requests.post(login_url, json=login_data)
token = response.json().get("token")

# 2. 设置请求头
headers = {
    "Content-Type": "application/json",
    "X-Authorization": f"Bearer {token}"
}

# 3. 分页获取设备列表
page = 0
page_size = 20
while True:
    devices_url = f"{BASE_URL}/api/tenant/devices?page={page}&pageSize={page_size}"
    resp = requests.get(devices_url, headers=headers)
    data = resp.json()
    
    for device in data["data"]:
        print(f"设备: {device['name']}, ID: {device['id']['id']}")
    
    if not data["hasNext"]:
        break
    page += 1

print("全部设备获取完毕")

这个脚本虽然简单,但包含了认证、分页、循环处理三个核心点。你把它跑通了,后面集成其他接口就是换换 URL 的事。

2.6 小结

这一章咱们把 REST API 集成的底子打好了。认证方式选 JWT,请求响应用 JSON,常用端点记住那七八个,分页过滤参数别搞错。嗯,这些东西看着简单,但实际项目中 80% 的问题都出在这些基础环节上。

下一章咱们会深入聊设备管理,包括批量操作、设备配置、属性更新这些实战内容。到时候我会分享更多我在项目中踩过的坑,保证让你少走弯路。