InterfaceMap 与 ServiceReferenceMap
声明一组具名 Interface 服务槽位,通过 ServiceReferenceMap 绑定同一 Runtime 中的多个目标服务。
InterfaceMap 用于声明“键到接口”的模块属性类型;对应的属性值必须是
ServiceReferenceMap。每个 valueMap 条目都是一个逻辑 ServiceReference,由调用模块自定义的稳定键
选择,同一个属性可以因此绑定多个符合接口契约的 Runtime 服务。
类型和值不能混用
InterfaceMap 只出现在 propertyDefinition[].type 中;ServiceReferenceMap 只出现在属性值、
defaultValue 编译结果和 Runtime 配置中。协议名称区分大小写,不能写成 interfaceMap、
InterfaceMAP,也不能把 valueMap 直接当作属性值顶层。
| 位置 | @type | 主要字段 | 用途 |
|---|---|---|---|
| 模块属性定义 | InterfaceMap | valueInterface | 约束每个映射值必须实现的接口 |
| 逻辑属性值 | ServiceReferenceMap | valueMap | 保存键到目标服务完整 businessId 的绑定 |
| 生命周期回调 | ServiceReferenceMap | valueMap | 保留映射结构,并把每个逻辑引用展开为可调用引用 |
在 module.json 中声明
下面的 channels 属性允许调用模块按 primary、backup 等业务键选择多个 Channel 服务。
valueInterface 与单值 Interface 的定义结构相同;其中的方法是调用方编译期的期望契约。
{
"propertyDefinition": [
{
"name": "channels",
"type": {
"@type": "InterfaceMap",
"valueInterface": {
"@type": "Interface",
"name": "Channel",
"methods": [
{
"name": "send",
"returnType": {
"@type": "DataType",
"type": "object",
"nullable": false
},
"paramDefinitions": [
{
"name": "payload",
"type": {
"@type": "DataType",
"type": "object",
"nullable": false
},
"required": true
}
]
}
],
"events": []
},
"nullable": false
},
"required": true,
"defaultValue": "{}"
}
]
}valueInterface描述所有映射值共同遵守的接口,不为不同键分别声明不同接口。- 映射键是调用模块自己的稳定业务键,不是模块名、Bundle 名、目标
businessId或方法名。 - 空默认值写成
"{}";模块版本编译后会形成空的ServiceReferenceMap。不要在定义中加入 Runtime 地址、token 或某个部署环境的可变服务 ID。 - 如果安装时就有明确且可移植的目标,可以在
defaultValue的 JSON 对象中写入ServiceReference条目;目标随安装结果变化时,应保持空默认值并在安装后配置。
需要复用公开 Type Definition 时,valueInterface 也可以使用受 Bundle
typeDefinitionDependencies 约束的 RefType。引用格式和版本范围见
Type Definition。
配置 ServiceReferenceMap
安装后先从目标工作区的 Runtime 服务目录读取每个目标服务的完整 businessId 和当前方法定义,再创建
properties.json:
{
"channels": {
"@type": "ServiceReferenceMap",
"valueMap": {
"primary": {
"@type": "ServiceReference",
"serviceId": "<primaryChannelBusinessId>"
},
"backup": {
"@type": "ServiceReference",
"serviceId": "<backupChannelBusinessId>"
}
}
}
}执行当前 CLI 的正式模块属性命令:
baijimu runtime app properties update \
<callerBusinessId> \
--workspace-id <workspaceId> \
--properties @properties.json--properties是模块属性的顶层部分更新;未出现的其他模块属性保持不变。channels一旦出现,本次提交的整个ServiceReferenceMap就是它的新值。要保留旧条目,必须把这些条目 一起放入本次valueMap,不能只提交新增键并假设平台会做映射内合并。- 清空映射时提交
{"@type":"ServiceReferenceMap","valueMap":{}}。不要提交裸{}、数组、null,也不要添加empty、_editingEntries等非协议字段。 - 每个
serviceId都必须是同一 Runtime 中可解析的完整businessId。Bundledependencies只保证安装 闭包和顺序,不替代这里的实际属性绑定。
属性写入时 Runtime 会校验所有嵌套引用并收敛相应访问关系。任一目标无法解析或引用无法授权时,本次配置 更新会明确失败,不会只保存可用的部分。
生命周期回调收到的结构
安装时的 BEFORE_DEPLOY 或安装后修改属性触发的 ON_CONFIG_UPDATE 会保持
ServiceReferenceMap.valueMap 结构,同时把每个逻辑 ServiceReference 展开为
ExternalServiceReference:
{
"channels": {
"@type": "ServiceReferenceMap",
"valueMap": {
"primary": {
"@type": "ExternalServiceReference",
"url": "https://<runtime-service-base>/<primaryChannelBusinessId>",
"serviceId": "<primaryChannelBusinessId>",
"token": "<opaque-reference-token>"
},
"backup": {
"@type": "ExternalServiceReference",
"url": "https://<runtime-service-base>/<backupChannelBusinessId>",
"serviceId": "<backupChannelBusinessId>",
"token": "<opaque-reference-token>"
}
}
}
}模块后端必须按整组值原子替换本地敏感配置,并通过相应条目的 url 和 token 调用目标方法。不得自行
拼接 Runtime 网关地址、解析 token、绕过 Runtime 直连目标 Hosted Backend,也不得把展开后的值写回
模块属性。完整调用和请求级用户委托分别见
模块服务间调用协议和
Runtime 用户委托。
与 Interface 和 InterfaceList 的区别
| 属性类型 | 属性值 | 选择方式 |
|---|---|---|
Interface | ServiceReference | 单个目标服务 |
InterfaceMap | ServiceReferenceMap.valueMap | 由调用模块定义的稳定键选择目标服务 |
InterfaceList | ServiceReferenceList.valueList | 按数组顺序遍历目标服务 |
不要因为当前只有一个目标就把 ServiceReference 塞进 InterfaceMap,也不要依赖 JSON 对象键的顺序来
表达优先级;需要有序选择时使用 InterfaceList。
验证清单
- 当前不可变模块版本的
propertyDefinition中存在InterfaceMap,且字段名是valueInterface。 - 每个候选目标 Bundle 已安装到同一 Runtime,目标完整
businessId、方法和paramDefinitions已回读。 properties.json使用ServiceReferenceMap.valueMap,每个值都是只含目标serviceId的ServiceReference。- 属性更新命令成功;失败时保留原错误并修正全部无效条目,不拆成部分成功或添加本地兜底。
- 生命周期 Endpoint 在
BEFORE_DEPLOY或ON_CONFIG_UPDATE收到相同键集合,且每个值都已展开为ExternalServiceReference;验证时不得输出 token。 - 模块后端按键选择引用并通过 Runtime 网关调用真实目标方法;删除或替换条目后停止使用旧引用并清除 本地副本。