百积木文档
开发指南平台应用、模块与 Bundle 开发模块开发

InterfaceMap 与 ServiceReferenceMap

声明一组具名 Interface 服务槽位,通过 ServiceReferenceMap 绑定同一 Runtime 中的多个目标服务。

接口容器的类型规则统一见类型系统:接口与方法;本页说明模块属性声明与服务绑定。

InterfaceMap 用于声明“键到接口”的模块属性类型;对应的属性值必须是 ServiceReferenceMap。每个 valueMap 条目都是一个逻辑 ServiceReference,由调用模块自定义的稳定键 选择,同一个属性可以因此绑定多个 Runtime 服务。提供方是否满足声明的接口由用户或其 AI 保证,平台绑定阶段不比对实际方法、事件、签名或接口实现身份。

类型和值不能混用

InterfaceMap 只出现在 propertyDefinition[].type 中;ServiceReferenceMap 只出现在显式配置的属性值和 Runtime 配置中。引用属性不允许 defaultValue。协议名称区分大小写,不能写成 interfaceMap、 InterfaceMAP,也不能把 valueMap 直接当作属性值顶层。

位置@type主要字段用途
模块属性定义InterfaceMapvalueInterface描述每个映射值的期望接口
逻辑属性值ServiceReferenceMapvalueMap保存键到目标服务完整 businessId 的绑定
生命周期描述ServiceReferenceMapvalueMap保留映射结构,嵌套引用不含 token
解析后的逻辑引用ServiceReferenceMapreference.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 的区别

属性类型属性值选择方式
InterfaceServiceReference单个目标服务
InterfaceMapServiceReferenceMap.valueMap由调用模块定义的稳定键选择目标服务
InterfaceListServiceReferenceList.valueList按数组顺序遍历目标服务

不要因为当前只有一个目标就把 ServiceReference 塞进 InterfaceMap,也不要依赖 JSON 对象键的顺序来 表达优先级;需要有序选择时使用 InterfaceList。

验证清单

  1. 当前不可变模块版本的 propertyDefinition 中存在 InterfaceMap,且字段名是 valueInterface。
  2. 每个候选目标存在于同一 Runtime,使用目标完整 businessId;用户或其 AI 自行确认方法和参数满足业务要求。
  3. properties.json 使用 ServiceReferenceMap.valueMap,每个值都是只含目标 serviceId 的 ServiceReference。
  4. 属性更新命令成功;失败时保留原错误并修正全部无效条目,不拆成部分成功或添加本地兜底。
  5. 生命周期 references.channels 收到相同键集合,每个值都是不含地址和 token 的 ServiceReference。
  6. 生命周期解析并保存 channels 访问配置,正常调用按本地键选择真实方法;删除或替换条目触发配置生命周期更新或停用。

本页内容