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

模块服务间调用协议

通过模块属性绑定 ServiceReference,插件按新协议领取当前凭据并调用同一 Runtime 中的目标模块方法。

模块 A 的独立后端需要调用同一 Runtime 中模块 B 的公开方法时,在模块 A 声明 Interface 属性, 把该属性设置为指向 B 的 ServiceReference。Runtime 自动生成来源服务到目标服务的访问关系和 token。 插件按生命周期与引用协议取得当前授权引用, 后端通过 Runtime 网关调用 B。

业务操作前按需解析引用访问

生命周期仅交付无 token 的引用描述;调用凭据通过引用访问解析协议获得,仅用于当前操作,不持久化。 插件开发、注册、阶段处理和安装隔离统一见生命周期插件开发

完整调用链

目标 Bundle 通过 dependencies 先安装
  -> 模块 A 声明 Interface 属性
  -> 模块 A 的属性设置为 ServiceReference(B)
  -> Runtime 校验绑定并收敛访问关系
  -> 插件保存新生命周期请求的安装定位与无凭据引用描述
  -> 每次业务操作前按授权 propertyKey 解析当前引用的访问信息
  -> 后端在当前操作中通过 Runtime 网关调用 B 的目标方法
  -> Runtime 校验来源服务、目标服务和允许的方法
  -> 模块 B 执行方法并返回统一响应

Bundle dependencies 只保证目标 Bundle 进入安装闭包和先于调用 Bundle 安装,不选择目标服务,也不设置 调用模块属性。设置属性就是绑定,没有另一套需要开发者调用的授权接口。声明与 CLI 示例见 ServiceReference 声明、绑定与运行时交付

本次解析的访问信息

响应的 data.reference 保留当前逻辑引用;按其中的 serviceId 读取 data.access 对应条目:

{
  "reference": {"@type": "ServiceReference", "serviceId": "<targetBusinessId>"},
  "access": {
    "<targetBusinessId>": {
      "url": "https://<runtime-service-base>/<targetBusinessId>",
      "token": "<opaque-reference-token>"
    }
  }
}

url 是 Runtime 网关中的目标服务基地址;token 是当前来源服务访问授权范围内目标方法的凭据。 它们由平台按当前绑定解析,调用方不得根据环境、域名或 businessId 自行拼接地址。 Map 使用 ServiceReferenceMap.valueMap;List 使用 ServiceReferenceList.valueList。先从逻辑结构选择目标, 再以 serviceId 读取调用信息。重复目标共用一份调用信息;任一目标无法授权时,本次解析失败。

HTTP 模块不能通过 position: "property" 接收引用。后端仅在当前操作中使用本次领取的凭据, 不得写入数据库、配置、日志、源码、Bundle 或前端状态。

调用具体方法

例如代码中的逻辑调用是:

xiaoxiangService.listManagedShops(params)

外部后端使用本次按需领取的引用,把接口方法转换为以下 HTTP 请求:

POST {access.url}/listManagedShops
Authorization: Bearer {access.token}
X-Runtime-Actor-Assertion: {currentRequest.actorAssertion}
Content-Type: application/json

X-Runtime-Actor-Assertion 只在当前入站 Runtime 调用已经建立用户身份时存在。调用方必须把它作为不透明、 请求级值转发;不得从生命周期 userId、业务参数或环境默认用户生成替代值。不需要用户身份的调用可以不带 该 Header。完整的单跳、链式轮换、异步边界和日志要求见 Runtime 用户委托

请求体顶层字段与目标方法当前 paramDefinitions 一一对应。目标方法声明一个名为 params 的参数时:

{
  "params": {
    "status": "ACTIVE"
  }
}

平台当前不生成语言级代理对象;xiaoxiangService.listManagedShops(params) 表示上面的标准 HTTP 调用, 不是另一个未发布的 SDK。调用方应从 Runtime 回读目标方法定义,不能自行复制一份可能漂移的方法签名。 响应按 CModel 错误模型 处理。

调用方不得自行把逻辑 ServiceReference 转换成地址或凭据,不直接请求目标 Hosted Backend 的 Controller 或部署地址。

上下文、权限和重试

引用 token 证明当前来源服务被允许调用当前目标服务的方法,但不自动代表某个最终用户。需要用户权限时, 调用方还必须转发当前请求由 Runtime 注入的 Actor assertion:

  • Runtime、工作区和来源服务身份由引用调用链确定,不从普通业务参数中接受同名字段。
  • 生命周期请求中的操作 userId 不能保存后用于业务调用。
  • 普通请求体或自定义头中的用户编号不是平台已验证的用户上下文。
  • 目标方法需要最终用户权限而可信用户上下文缺失时,必须拒绝,不能回退到安装用户或固定管理员。
  • Actor assertion 不能持久化或用于请求结束后的重试;服务链跨到新目标后,由 Runtime 为该目标后端自动 轮换下一跳 assertion,外部服务不签名。

调用方对 HTTP 200 响应检查 CModel errorCode;非 200、连接中断或超时时属于传输失败,执行结果可能未知。只有目标方法 本身声明幂等,或请求携带该方法规定的幂等键时,才允许自动重试。旧 token 返回未授权时不循环重试, 本次操作应失败,并检查活动安装和引用授权;不能回退到旧凭据或重新注册另一套外部服务。

可执行的端到端步骤

  1. 在 Bundle dependencies 中声明目标 Bundle 的 Cargo 版本需求,并确认 Runtime 解析出的精确版本满足需求。
  2. 在模块 A 当前版本中声明 xiaoxiangServiceInterface 属性,并安装模块 A。
  3. 回读模块 B 的完整 businessIdlistManagedShops 方法及 paramDefinitions
  4. 使用正式的 baijimu runtime app properties update 命令,把模块 A 的 xiaoxiangService 设置为 指向模块 B 的 ServiceReference;完整参数见 ServiceReference 页面,不要自行拼接平台接口路径。
  5. 插件按新协议接收并校验安装定位,在业务操作前按授权属性领取当前地址和调用凭据,不要输出 token。
  6. 由模块 A 后端按上述 JSON POST 请求调用 listManagedShops;当前请求存在 Actor Header 时同时原样 转发,确认 HTTP 200 并检查 CModel errorCode
  7. 修改或清除属性后,确认下一次领取反映当前绑定,撤销后的引用不能继续调用。

如果第 5 步领取失败,应检查安装环境、活动安装、插件身份、绑定协议、授权属性和当前目标关系; 不能用硬编码地址或非公开凭据绕过引用授权。

本页内容