模块事件与发布机制
区分事件声明、发布和订阅,并通过当前 Runtime 安全发布模块事件。
协议状态(2026-10-21):资源凭据领取与生命周期通知是已确认、尚未实现和定版的目标设计。插件在 AFTER_RESOURCES 按安装与资源主动领取自己的入口和凭据,回调不携带秘密;配置变化仍走生命周期通知,业务请求不解析引用。Backend 保留插件身份关联,轮换只撤销自己的旧凭据;ACS 不改,不做多插件协调。下文版本化示例保留用于现有协议维护,不能把新 API 字段发送给旧接收端。
事件参数的类型、必填与可空规则统一见类型系统。
模块事件是安装到 Runtime 的类型化业务能力。事件名和载荷由 Module 版本声明;发布方调用当前 Runtime 物化出的事件方法;订阅、触发和投递由独立资源管理。三者不是同一个动作:
module.json events 声明
-> 创建不可变 Module 版本并随 Bundle 发布
-> 安装到目标 Runtime,物化事件方法和发布能力
-> 工作流或模块后端发布事件
-> 已安装的 Event Trigger / 订阅消费事件事件声明、事件发布和事件订阅是三份独立合同。因此,新增 events 不会自动发送事件,也不会自动创建
工作流、Webhook 或 Event Trigger。事件生产方必须
显式发布;需要自动触发后续动作时,还要把相应触发资源纳入 Bundle。
订阅端的配置和命令见 Event Trigger 绑定工作流与输入映射:
选择来源与工作流、用 =event.data... 映射启动输入、创建触发器版本并随 Bundle 安装。
地址从哪里来
事件发布地址不写死,也不由 Bundle 作者填写。Runtime 会根据目标环境和当前安装实例生成可调用的事件方法,
并同时生成作用于该 Runtime 的授权。应用代码和工作流都不能保存或推断内部主机、端口、服务地址、Runtime
businessId 或事件平台凭据。
对调用方而言,事件方法与普通 Runtime 方法使用同一调用入口和授权边界;不存在需要开发者选择的“事件 专用网关”或额外协议。地址在环境迁移、重新安装或授权轮换后可以变化,所以必须使用当前 Runtime 物化并 交付的值。
从工作流发布
工作流使用 emit_event 节点。module 必须填写从目录选择的 {bundleId, moduleId},
eventName 必须是该 Module 当前版本声明的事件名,payload 必须符合其 paramDefinitions:
{
"type": "emit_event",
"id": "emit_order_status_changed",
"name": "发布订单状态变更",
"eventName": "orderStatusChanged",
"payload": {
"orderId": "{{input.orderId}}",
"status": "{{context.order.status}}",
"occurredAt": "{{context.order.occurredAt}}"
},
"idempotencyKey": "order-status:{{input.orderId}}:{{context.order.status}}",
"timeoutSecs": 30,
"module": {
"bundleId": "example-orders",
"moduleId": "orders"
}
}安装物化时,平台根据目标 Runtime 的资源 Owner 当前库存、精确资源版本及授权解析本包模块领域引用,并生成执行授权。Workflow
定义中不得出现 Runtime businessId、原始 URL 或 Authorization。通用 http 节点不能替代
emit_event:它不提供 模块领域引用解析、事件合同校验和 Runtime 作用域授权。
完整节点字段见工作流与 历史 Workflow Definition JSON Schema 5.0.0。
从独立模块后端发布
模块方法调用 Hosted Service 或其他独立后端,并由后端在业务事务成功后发布事件时,应让 Runtime 把发布 目标作为一对只读能力交付给后端:
<eventName>_event_url:当前 Runtime 生成的事件方法 URL。<eventName>_event_authorization:只允许调用该 Runtime 能力的完整 Authorization 值。
如果 methodBody 需要引用这两个值,先在 module.json 的 propertyDefinition 中声明同名属性。URL 必须
只读;Authorization 必须同时只读且敏感:
{
"propertyDefinition": [
{
"name": "orderStatusChanged_event_url",
"type": {
"@type": "JsonSchema",
"schema": {
"type": [
"string",
"null"
]
}
},
"description": "由当前 Runtime 生成的 orderStatusChanged 发布地址。",
"isSensitive": false,
"readOnly": true,
"required": false
},
{
"name": "orderStatusChanged_event_authorization",
"type": {
"@type": "JsonSchema",
"schema": {
"type": [
"string",
"null"
]
}
},
"description": "由当前 Runtime 生成的 orderStatusChanged 发布授权。",
"isSensitive": true,
"readOnly": true,
"required": false
}
]
}再在调用后端的 HTTP 方法中用 position: "property" 映射。下列 Header 名是模块与自身后端约定的示例,
不是平台保留 Header:
{
"header": {
"X-Module-Event-Url": {
"required": true,
"position": "property",
"key": "orderStatusChanged_event_url"
},
"X-Module-Event-Authorization": {
"required": true,
"position": "property",
"key": "orderStatusChanged_event_authorization"
}
}
}后端从受信任的模块调用中读取这对值,向 URL 发送符合事件 paramDefinitions 的 JSON,并把 Authorization
值原样放入请求头。URL 已经是完整事件方法地址;不要追加内部路径,也不要把 Authorization 改造成另一种
token。
POST <orderStatusChanged_event_url>
Authorization: <orderStatusChanged_event_authorization>
Content-Type: application/json
{
"orderId": "order-123",
"status": "approved",
"occurredAt": 1788537600000
}从 Bundle 插件的异步 Worker 发布
跨请求运行的 outbox 或后台 Worker 使用插件身份 Token,按安装身份、Module Locator 和 eventName
主动查询当前事件调用能力。它与 interface 属性使用同一个凭据解析接口;无需事件自引用属性或额外授权开关。
生命周期中读取 access[eventName] = {url, token} 并保存为受保护的事件运行配置;每次投递和业务重试直接使用本地完整 URL 与 Token,不重新解析。
具体声明、Bundle 插件授权和重试规则见 Bundle 插件异步发布事件。
安全与生命周期规则
- URL 与 Authorization 是当前 Runtime 颁发的一对能力,必须成对使用、成对更新;不得跨工作区或跨 Runtime 复用。
- 不允许终端用户提交任意事件 URL 或 Authorization。浏览器、表单、工作流输入和普通业务 API 都不应包含 这两个字段。
- Authorization 不进入日志、响应、事件载荷或任务参数。方法调用交付的能力只用于当前操作; 跨请求异步投递的事件凭据在 Bundle 生命周期中解析并保存到受保护的运行配置,后续生命周期负责更新或清理。
- 后端不得按工作区 ID、项目 ID、域名规则或环境名称拼接发布地址,也不得直接调用内部事件服务。
- 发布成功只证明事件已被接受;后续动作还取决于目标 Runtime 中是否安装并启用了匹配的 Event Trigger 或 订阅,以及其投递与重试状态。
发布前验证
- 从精确 ModuleVersion 回读事件名和
paramDefinitions,确认来自预期 Git commit。 - 检查 Bundle Manifest 精确引用该 ModuleVersion,并包含需要的 Event Trigger 资源。
- 安装或升级 Bundle 后,从目标 Runtime 回读事件方法;不要只检查项目工作区文件。
- 分别验证工作流
emit_event和后端回调所需的入口;不使用生产凭据做本地硬编码测试。 - 发送一条带稳定业务幂等键的测试事件,再检查订阅触发、Webhook/动作结果和失败重试。
事件声明的 JSON 结构与版本演进规则见模块定义开发。