InterfaceMap 与 ServiceReferenceMap
声明一组具名 Interface 服务槽位,通过 ServiceReferenceMap 绑定同一 Runtime 中的多个目标服务。
接口容器的类型规则统一见类型系统:接口与方法;本页说明模块属性声明与服务绑定。
InterfaceMap 用于声明“键到接口”的模块属性类型;对应的属性值必须是
ServiceReferenceMap。每个 valueMap 条目都是一个逻辑 ServiceReference,由调用模块自定义的稳定键
选择,同一个属性可以因此绑定多个 Runtime 服务。提供方是否满足声明的接口由用户或其 AI 保证,平台绑定阶段不比对实际方法、事件、签名或接口实现身份。
类型和值不能混用
InterfaceMap 只出现在 propertyDefinition[].type 中;ServiceReferenceMap 只出现在显式配置的属性值和
Runtime 配置中。引用属性不允许 defaultValue。协议名称区分大小写,不能写成 interfaceMap、
InterfaceMAP,也不能把 valueMap 直接当作属性值顶层。
| 位置 | @type | 主要字段 | 用途 |
|---|---|---|---|
| 模块属性定义 | InterfaceMap | valueInterface | 描述每个映射值的期望接口 |
| 逻辑属性值 | ServiceReferenceMap | valueMap | 保存键到目标服务完整 businessId 的绑定 |
| 生命周期描述 | ServiceReferenceMap | valueMap | 保留映射结构,嵌套引用不含 token |
| 解析后的逻辑引用 | ServiceReferenceMap | reference.valueMap | 返回当前业务键与目标服务关系 |
| 本次访问信息 | 调用信息对象 | access[相对选择器路径] | 返回来源模块属性路径 URL 与来源资源凭据 |
在 module.json 中声明
下面的 channels 属性允许调用模块按 primary、backup 等业务键选择多个 Channel 服务。
valueInterface 与单值 Interface 的定义结构相同;其中的方法是调用方编译期的期望契约。
{
"propertyDefinition": [
{
"name": "channels",
"type": {
"@type": "InterfaceMap",
"valueInterface": {
"@type": "Interface",
"name": "Channel",
"methods": [
{
"name": "send",
"async": false,
"returnType": {
"@type": "JsonSchema",
"schema": {
"type": "object"
}
},
"paramDefinitions": [
{
"name": "payload",
"type": {
"@type": "JsonSchema",
"schema": {
"type": "object"
}
},
"required": true
}
]
}
],
"events": []
},
"nullable": false
},
"required": true
}
]
}valueInterface描述所有映射值共同遵守的接口,不为不同键分别声明不同接口。- 映射键是调用模块自己的稳定业务键,不是模块名、Bundle 名、目标
businessId或方法名。 - 属性定义必须省略
defaultValue,包括空对象、"{}"和null。未配置时不自动创建映射或选择服务。 - 映射目标由安装后的显式属性配置确定。需要空映射时,配置
{"@type":"ServiceReferenceMap","valueMap":{}};这是显式空容器,与未配置不同。 InterfaceList遵循相同规则:定义中无默认值,显式空列表配置为{"@type":"ServiceReferenceList","valueList":[]}。
需要复用公开 Type Definition 时,valueInterface 也可以使用 RefType,通过 Module 的
typeImports 别名或完整 URI 引用精确版本。Bundle 不参与类型版本选择。引用格式和兼容性见
Type Definition。
配置 ServiceReferenceMap
安装后从目标工作区的 Runtime 服务目录取得每个目标服务的完整 businessId,由用户或其 AI 核对业务所需方法,再创建
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,并满足归属和授权要求。绑定阶段不比较提供方的实际接口。Bundle 安装只交付定义,不自动绑定目标;参见安装与资源绑定。
属性写入时 Runtime 会校验本次属性的容器结构、引用身份和授权,并收敛相应访问关系;不读取目标执行定义比较方法。任一目标无法解析或引用无法授权时,本次配置 更新会明确失败,不会只保存可用的部分。
新插件收到的引用描述
新插件生命周期请求的 references 保持 ServiceReferenceMap.valueMap 结构。
各条目都是不含地址和 token 的 ServiceReference 描述。下面展示 references 中的 channels:
{
"channels": {
"@type": "ServiceReferenceMap",
"valueMap": {
"primary": {
"@type": "ServiceReference",
"serviceId": "<primaryChannelBusinessId>"
},
"backup": {
"@type": "ServiceReference",
"serviceId": "<backupChannelBusinessId>"
}
}
}
}生命周期中,插件以 propertyKey: "channels" 按
生命周期与引用协议解析当前整组引用的访问权限,
再按业务选择器读取 access["/primary"] 或 access["/backup"],将平台返回的完整 URL、来源资源 Token 与选择关系保存为受保护的本地运行配置。
单值引用使用空字符串键;List 使用 /0、/1;嵌套选择器按相对 JSON Pointer 编码。相同目标的不同属性路径分别保留,共用来源 token,不能按 serviceId 去重。
正常业务调用及重试使用该配置,后续生命周期负责更新或停用;凭据不写回逻辑模块属性。
不能自行拼接 Runtime 网关地址、解析 token 或直连目标 Hosted Backend。完整调用和请求级用户委托分别见
模块服务间调用协议和
Runtime 用户委托。
同一目标绑定到 primary 和 backup 时,仍返回 /primary 与 /backup 两条来源属性 URL;token 相同,不合并条目。
机器可读示例见重复目标的属性路径访问。
与 Interface 和 InterfaceList 的区别
| 属性类型 | 属性值 | 选择方式 |
|---|---|---|
Interface | ServiceReference | 单个目标服务 |
InterfaceMap | ServiceReferenceMap.valueMap | 由调用模块定义的稳定键选择目标服务 |
InterfaceList | ServiceReferenceList.valueList | 按数组顺序遍历目标服务 |
不要因为当前只有一个目标就把 ServiceReference 塞进 InterfaceMap,也不要依赖 JSON 对象键的顺序来
表达优先级;需要有序选择时使用 InterfaceList。
验证清单
- 当前不可变模块版本的
propertyDefinition中存在InterfaceMap,且字段名是valueInterface。 - 每个候选目标存在于同一 Runtime,使用目标完整
businessId;用户或其 AI 自行确认方法和参数满足业务要求。 properties.json使用ServiceReferenceMap.valueMap,每个值都是只含目标serviceId的ServiceReference。- 属性更新命令成功;失败时保留原错误并修正全部无效条目,不拆成部分成功或添加本地兜底。
- 生命周期
references.channels收到相同键集合,每个值都是不含地址和 token 的ServiceReference。 - 生命周期解析并保存
channels访问配置,正常调用按本地键选择真实方法;删除或替换条目触发配置生命周期更新或停用。