HTTP API
AetherEdge 运行六项 HTTP 服务,但远程应用程序只有一个网络边界:端口 6005 上的 aether-api。本页介绍网关、其服务本地合约以及在其上应用的安全约定。
每个运行中服务生成的 OpenAPI 文档,都是其路径、参数、请求与响应结构、 状态码、媒体类型和操作级安全要求的权威来源。可以使用配套的 Swagger UI 探索和调用这些操作。
内置文档
“内置文档”标题的链接| 服务 | 默认边界 | Swagger 界面 | OpenAPI JSON |
|---|---|---|---|
aether-io |
环回 | http://127.0.0.1:6001/docs |
http://127.0.0.1:6001/openapi.json |
aether-automation |
环回 | http://127.0.0.1:6002/docs |
http://127.0.0.1:6002/openapi.json |
aether-history |
环回 | http://127.0.0.1:6004/docs |
http://127.0.0.1:6004/openapi.json |
aether-api |
远程网关 | http://<edge-host>:6005/docs |
http://<edge-host>:6005/openapi.json |
aether-uplink |
环回 | http://127.0.0.1:6006/docs |
http://127.0.0.1:6006/openapi.json |
aether-alarm |
环回 | http://127.0.0.1:6007/docs |
http://127.0.0.1:6007/openapi.json |
Swagger 是通过每项服务的 swagger-ui Cargo 功能选择加入的。要将其包含在安装程序构建的所有六个服务中,请使用:
./scripts/build-installer.sh <version> <arch> -s rust --enable-swagger启用后,/docs 和 /openapi.json 是公开路由。Swagger 不会绕过受保护操作的身份验证,但会公开接口结构及其他内部 API 信息。仅在受信任的调试或开发网络中启用它。
曝光边界
“曝光边界”标题的链接只有 aether-api 是面向远程的服务。其经过身份验证的应用程序网关公开五个固定命名空间,并仅将它们转发到配置的环回服务:
| 远程命名空间 | 服务本地业主 |
|---|---|
/api/v1/io/* |
aether-io |
/api/v1/automation/* |
aether-automation |
/api/v1/history/* |
aether-history |
/api/v1/uplink/* |
aether-uplink |
/api/v1/alarm/* |
aether-alarm |
目标是由命名空间选择的,而不是由调用者输入选择的。启动验证仅接受显式环回 HTTP 源。网关保留原始签名的承载令牌以及一小组记录的命令和条件请求标头;它丢弃调用者提供的参与者标头并清理上游传输错误。直接服务端口保留在内部,不得从设备发布。
生成的应用程序和下游产品接口在端口 6005 上使用相应的网关前缀路径。在当前整合阶段,服务本地 OpenAPI 仍是精确的操作契约;客户端通过上面的固定命名空间转换其内部路径。这不会使服务本地端口成为受支持的客户端接口。缺少的操作仍然必须通过所属应用程序边界添加,而不能由界面自行发明、直接附加到 SHM 或实现为存储写入。
环回是部署边界,而不是身份凭证。 IO 通道调试加上选定的自动化和警报命令在操作边界进行身份验证,但 io、历史、上行链路、自动化和警报中的许多其他本地管理路由仍然依赖于主机隔离。不要因为直接服务端口的某些操作声明了承载方案而推断其公开是安全的。
当前完整通道配置查询可以包括协议参数和每通道日志记录配置。它仍然存在兼容性债务,等待经过编辑、经过身份验证的应用程序查询功能。保持 io 端口处于环回状态,并且不要将该响应代理给不受信任的客户端。
认证模型
“认证模型”标题的链接aether-api 使用签名的访问 JWT 保护其管理路由。 REST 客户端仅在标准标头中发送它:
Authorization: Bearer <access-token>登录、刷新令牌生命周期端点、服务运行状况以及编译后的文档路由构成网关 OpenAPI 文档描述的公共传输表面。除非明确启用,否则公共注册将被禁用。所需的 JWT_SECRET_KEY 必须至少包含 32 个字节,并且必须在源代码控制之外进行管理。
网关 WebSocket 也经过身份验证。仅当实际的 WebSocket 升级时才接受其记录的 ?token=... 后备; REST 查询字符串标记被拒绝。不支持 WebSocket 控件写入。
网关在转发任何命名空间请求之前需要访问 JWT。然后,所属服务应用特定于操作的授权:
- io 通道创建、更新、删除、启用和禁用需要具有
io.channel.manage的管理员或工程师承载 JWT; - 自动化设备操作接受承载访问 JWT 或专用的
AetherService <token>上行链路凭据; - 自动化规则管理和手动执行需要具有记录的功能的管理员或工程师承载 JWT操作;
- 警报规则突变和警报解决需要管理员或工程师承载 JWT;
- 转发的身份标头和环回可达性不满足这些受保护的命令边界。
受控命令
“受控命令”标题的链接可以更改通道配置、设备、规则、处理或警报状态的命令,会在 OpenAPI 中声明其风险、权限、幂等性、确认和审核策略。应用程序命令边界强制执行这些声明;HTTP 处理程序不得直接写入 SHM 或存储。
对于受保护的变更,请严格遵循操作结构。根据操作的不同,显式确认会通过 x-aether-confirmed: true 或请求正文传递。在支持时提供 x-request-id,使重试和审核记录共享稳定的关联 ID。不要假设系统会通过未声明的标头转发确认或身份。
已接纳的受控命令会在 OpenAPI 描述的响应中包含 request_id 和审核结果。如果调度或持久化成功,但最终审核记录追加失败,则操作仍会被接纳,其审核状态会标记为不完整且不可重试。此时应保留关联 ID,不要自动再次提交命令。若连操作尝试都无法记录,系统会在调度前拒绝该操作。
设备命令接受意味着本地命令平面接受了请求;它并不能证明物理设备执行了它。使用反馈遥测进行闭环确认。
对于通道调试,SQLite 中的期望配置与活动协议运行时有意保持独立。现有资源变更可以使用可选的 x-aether-expected-revision 提供比较并交换保护。提交期望状态后,已接纳的响应可能报告等待激活或运行时投影降级;应通过 request_id 和 resulting_revision 协调,而不是自动重复非幂等变更。确切的标头、回执字段和每项操作的状态码由 io Swagger 文档定义。
响应兼容性
“响应兼容性”标题的链接大多数业务处理程序返回共享成功信封:
{ "success": true, "data": { "...": "..." }, "metadata": { "...": "..." } }当为空时,metadata 被省略。运行状况探测、服务横幅、WebSocket 升级、CSV 导出和严格的数据处理响应有意使用自己的表示形式。
错误响应仍在迁移,并且可能使用以下兼容性形状之一:
{ "success": false, "error": { "code": 400, "message": "..." } };{ "success": false, "message": "..." };- 版本化数据处理
{ "error": { "code": "...", ... } }表单; - 与
error_code、category和retryable的平面AetherError映射。
客户端必须将操作的 OpenAPI 状态和响应内容类型视为权威,并容忍记录的兼容性形状。请勿从其他服务推断通用错误架构。
贡献者合约
“贡献者合约”标题的链接当路由、架构、安全规则、响应或功能门发生更改时,请在同一更改中更新所属服务生成的 OpenAPI 注释和测试。远程示例必须使用网关前缀形式,而本地合约测试可以使用拥有的环回服务。不要将第二个端点列表添加到 Markdown。运行六项服务奇偶校验:
./scripts/check-openapi-contracts.sh此检查会编译可选的 Swagger 功能,并验证每个服务拥有的 Router/OpenAPI 契约。它也会在 Rust 持续集成工作流中运行。