通信、认证与错误处理
2.1 阅读本参考的约定
下文接口均写出完整 /v1/api 路径。标记“响应 data”的 JSON 只展示统一信封中的 data;标记“完整响应”时包含 code、msg、data。同组的无参数启停接口可共用请求、响应和错误说明。
- 未列出请求体的 GET/DELETE 接口不需要 JSON 请求体。
- 明确写“无请求体”的 POST 可不发送内容;不要自动为所有接口附加
{}。 - 表格中的“必填”区分服务端显式校验与业务使用要求;部分旧接口把缺失的数值反序列化为 0,客户端仍应显式填写目标位姿,避免意外请求原点。
- 有
omitempty的字段可能完全不出现。业务数据为空时可能是null、空数组或空对象,按各接口定义处理。 - 下游透传对象不承诺固定的完整字段集合;本文列出的示例值不代表所有设备都具备对应适配器、动作或参数。
2.2 响应信封与例外
常规 JSON 接口使用:
{"code":0,"msg":"success","data":null}
| 字段 | 类型 | 说明 |
|---|---|---|
code | integer | 业务码;0 为成功 |
msg | string | 成功通常为 success;失败为描述文本,不作为稳定枚举 |
data | any / null | 业务对象、数组、结果细节,或无数据 |
创建资源通常也返回 HTTP 200,不是统一使用 201。客户端同时检查 HTTP 状态和业务码。HTTP 200 + code=3101 仍表示清障忙碌;参数接口还需检查内部 success。
例外:文件下载、PNG、ZIP 是二进制;系统 SSE 和 ASR 是事件流;WebSocket 升级后是帧协议;Swagger/WebUI 为网页。GET /healthz 在当前实现中使用上述信封,不是裸 {"status":"ok"}。下载失败通常返回 JSON 错误,但文件服务阶段的错误也可能是原生 HTTP 错误,读取前检查状态和 Content-Type。
2.3 认证规则
API 是否校验 token 由实际启动入口共同决定,不能只看 run_mode=prod,也不能仅凭 auth/me 返回 developer 就判断为 dev 模式。 当前路由装配条件为:
authRequired := cfg.Device.RunMode != "dev" && !cfg.FactoryInspection && !cfg.FactoryTokenBypass
| 运行方式 | 有效模式 / 标志 | API Bearer | auth/me 身份 |
|---|---|---|---|
| 普通生产启动,未启用兼容绕过 | prod,两个绕过标志均 false | 必须校验 | token 对应的用户名 |
| 开发启动 | dev | 不校验 | developer |
标准包接管入口 -standard-boot | 按 prod 加载和校验,FactoryTokenBypass=true | 不校验 | developer |
| 制造放行后的运营接管 | prod,FactoryTokenBypass=true | 不校验 | developer |
| 制造检测业务运行态 | FactoryInspection=true | 使用独立制造会话门控,不走普通 Bearer | factory_local |
FactoryTokenBypass 是启动装配设置的内部标志(toml:"-"),不是给客户端或配置文件任意切换的公开开关。标准包接管会在内存中按 prod 校验旧配置,即使磁盘配置仍写 dev,也不能只读该文件判断实际模式。普通生产启动与带 -standard-boot 的兼容接管须区分。
仅在 authRequired=true 时,除下表外所有业务接口都需要 Bearer 请求头,且只能提供一份 Authorization。本文后续“受保护”“需要 Bearer”均指注册在该业务路由组,实际是否校验遵循此表;免 token 运行方式可省略示例中的 Authorization 头。
| 接口 | 认证规则 |
|---|---|
GET /healthz | 公开 |
GET /v1/api/systems/device | 公开 |
POST /v1/api/auth/verify | 公开入口;authRequired=true 时校验 JSON token,否则直接返回 developer |
GET /v1/api/terminal/ws | 不走 Bearer;独立终端令牌规则见 20.2;兼容接管会清空传给终端 handler 的有效 token |
启用 Bearer 校验时,[auth.tokens] 至少配置一条用户名与静态令牌,令牌至少 32 字节,用户名与令牌均不可重复。目前各令牌权限相同,用户名用于身份显示与审计,不代表角色权限。认证失败为 HTTP 401、code=1006,并带 WWW-Authenticate: Bearer。
Linux/SSH 登录用户名和密码与这套 API 认证无关。HTTP 不使用系统账号密码校验,developer 是绕过 Bearer 时由中间件注入的固定身份,不是设备上必须存在的 Linux 用户。API 免 token 也不代表 MQTT、Mender 或云接入免认证。
服务端支持跨域并允许 Authorization 头。启用 Bearer 校验时,浏览器 SSE 和下载同样需要授权;普通 img src、EventSource 无法自由附加 Bearer,可用带请求头的 fetch。免 token 模式不受该请求头限制。
2.4 时间、坐标与名称
| 项目 | 约定 |
|---|---|
| 普通创建/更新时间 | RFC 3339 字符串,可能含小数秒;以返回的时区偏移为准 |
地图 created_time、modified_time | Unix 秒,number |
任务事件 timestamp、进度 updated_at | Unix 毫秒,integer |
MQTT 注册/心跳 ts | RFC 3339 字符串 |
x、y、theta | 平面位置和朝向;常用地图导航使用米、弧度,见下方证据边界 |
frame_id | 常用 map(地图坐标系)、base_footprint(机器人本体参考系);建议显式传入 |
| 地图名称 | 1–64 个 Unicode 字母/数字及 .、_、-;UTF-8 最多 240 字节;不以 . 开头、不为纯数字;不自动归一化 |
坐标说明:导航进度实现用 ROS 里程计四元数计算弧度 yaw,并按米统计距离;足迹校验也明确使用米。这支持当前导航集成使用米/弧度。HTTP 转发层本身不做单位换算,也未对所有下游协议强制声明单位;更换导航镜像后须确认其协议,尤其是标定结果的角度单位和旋转方向,不能把上述约定套到所有下游字段。 rotate 步骤是 base_footprint 下的原地相对旋转请求,不是 map 下的绝对终点角度。
名称放入 URL 时对单个路径段做百分号编码;文件相对路径逐段编码,保留 / 分隔;查询参数用标准 URL 编码。
2.5 同步、异步与重试
| 操作 | HTTP 返回意味着什么 | 正确完成条件 |
|---|---|---|
/nav/startup | 同步完成准备步骤或返回失败步骤 | 环境就绪;尚未开始导航任务 |
| Missions / 旧导航启动 | 已提交;最多约 500 ms 快速失败检查 | 任务状态为 completed |
/mapping/container/start | 已提交;最多约 5 s 快速失败检查 | 建图容器和建图状态可查询;最终还需结束保存 |
/mapping/container/stop | 已请求停止当前建图 | 本机任务成功结束,地图文件验证通过 |
/nav/container/stop | 后台停止请求已发起 | 容器状态不再 running |
| 通用容器启停 | 后台动作受理 | 轮询容器详情确认状态 |
| 参数保存 | 持久化和/或运行时应用的分项结果 | 检查每个参数;离线保存待启动回放 |
| 软件升级 | 返回升级任务 | 由 OTA 任务 state 确认,不使用 navigation 任务状态枚举 |
查询失败可按 1、2、4 秒退避重试;运动、建图、升级等创建请求超时后先查询现状,不自动重发。Missions 没有 HTTP 幂等键参数;需要应用级幂等时可使用 /tasks/submit 的 idempotency_key。没有全局通用的 Idempotency-Key HTTP 头。
2.6 业务错误码
| code | HTTP | 含义与处理 |
|---|---|---|
| 0 | 200 | 成功;异步任务仍需跟踪 |
| 1001 | 400 | 参数或格式错误,修改请求 |
| 1002 | 404 | 资源不存在 |
| 1003 | 500 | 内部错误,检查日志 |
| 1005 | 502 | 下游不可用或调用失败,检查对应服务 |
| 1006 | 401 | 认证失败 |
| 1007 | 409 | 资源、版本或操作状态冲突 |
| 2001 | 500 | 导航域错误 |
| 3001 | 500 | 建图域错误 |
| 4001 | 500 | 通用容器管理错误 |
| 4002 | 409 | 容器互斥、停机保护或参数方案切换被策略拒绝 |
| 4003 / 4004 | 500 | 容器启动超时 / 健康检查失败的预留业务码,不代表所有异步失败都会回传这些码 |
| 4005 | 500 | Docker 运行时不可达 |
| 5001 | 500 | 本机任务错误;包含部分提交、取消和幂等冲突 |
| 6001 | 500 | 地图域错误 |
| 3101 | 200 | 清障忙碌,稍后重试 |
| 3102 / 3103 | 502 | 地形记忆重置失败 / 重置后感知等待超时 |
| 3104 / 3105 | 502 | 局部 / 全局代价地图清除失败 |
| 3106 | 400 | 清障请求格式或 scope 非法 |
| 3000 | 504 | 清障下游导航响应超时 |
| 5000 | 500 | 清障下游内部异常 |
未归类的业务码由公共映射返回 HTTP 422。不同入口不一定把同一个底层错误映射为相同业务码,例如通用 /tasks/submit 多数提交错误为 5001,建图专用入口可把忙碌映射为 1007。错误示例:
{"code":1001,"msg":"mode is required","data":null}