调用模块方法
平台应用前端通过标准 SDK 和 App Gateway 逐方法路由调用已授权的 Runtime 模块方法。
平台应用前端调用模块能力时,统一通过 app-gateway。页面不能直接请求模块服务地址或平台内部接口。
当前部署的对外 App Gateway 前缀是 /app-gateway/api;/lowcode3/api 是历史或其他
部署形态的路径,不能作为当前环境的 API 地址。完整的网关选择、授权链和配置方法见
App Gateway 接入与配置。
调用协议
POST /app-gateway/api/workspace-runtime/apps/{installId}/invoke
Authorization: Bearer {appClientToken}
Content-Type: application/jsoninstallId 是当前工作区的平台应用安装标识。请求中的 target 和 method 必须与当前不可变
Platform Application 版本的 methodDefinitions 完全一致。标准 SDK 从启动会话取得 installId。
请求参数
POST 请求体包含声明目标、方法名和模块方法参数对象:
POST /app-gateway/api/workspace-runtime/apps/pia_xxx/invoke
Authorization: Bearer ag1_xxx
Content-Type: application/json{
"target": {
"type": "module",
"bundleId": "course-management",
"moduleId": "course-directory"
},
"method": "createCourse",
"params": {
"code": "COURSE-001",
"name": "高等数学",
"teacherId": 123,
"tags": [
"必修",
"一年级"
]
}
}params 是方法参数对象,其中字段与模块方法 paramDefinitions 中的参数名称一一对应:
- 必填、类型、对象结构和数组元素服从模块方法定义。
- 无参数方法的
params也必须是 JSON 空对象{}。 - 不要传递 Runtime
service、methodBody、userId或平台身份请求头。 methodBody只描述特定模块实现如何访问后端 HTTP 服务,不属于前端调用协议。
例如 createCourse 定义了 code、name、teacherId 和 tags,页面就发送同名
JSON 字段。模块内部是否把 teacherId 转换为 teacher_id,属于模块实现,不影响
页面协议。
module 与 interface
固定依赖应直接使用 Module 领域引用。声明和调用使用同一个 target:
{
"target": {
"type": "module",
"bundleId": "course-management",
"moduleId": "course-directory"
},
"methods": [
"listWorkspaceUsers",
"createCourse"
]
}只有当业务明确需要可替换实现时才使用 interface。例如版本声明:
{
"target": {
"type": "interface",
"name": "course-directory"
},
"methods": ["listWorkspaceUsers", "createCourse"]
}Bundle 平台应用资源声明的接口来源为:
{
"interfaceBindings": {
"course-directory": {
"bundleId": "course-management",
"moduleId": "course-directory"
}
}
}安装计划根据当前 Bundle 及其依赖 Bundle 的模块领域引用 解析接口。具体 Runtime service 绑定值和
调用身份只保存在安装态,由平台动态维护,不进入平台应用源码、Bundle Manifest 或浏览器。
无论选择 module 还是 interface,原始 service、具体 businessId 和 * 通配声明都不能用于新版本。
查询当前工作区用户
平台应用没有“登录后可以任意调用平台后端模块”的权限。平台已经通过 workspace-core 的
工作区管理 Module 提供 listWorkspaceMembers;业务 Bundle 必须显式依赖 workspace-core,
平台应用版本再声明并绑定这个方法。页面仍然通过标准 SDK 调用:
const members = await client.call(
{
type: "module",
bundleId: "workspace-core",
moduleId: "2108",
},
"listWorkspaceMembers",
{},
);方法从经过验证的调用上下文取得当前工作区和当前用户,不接受页面传入的 workspaceId 或
userId 作为可信身份。依赖声明、真实 领域引用、应用能力绑定、发布安装和验证步骤见
示例:查询工作区成员。
响应
调用成功时,app-gateway 返回统一 CModel 响应,模块方法返回值位于 data:
{
"contractVersion": "1.0.0",
"errorCode": "0",
"data": {
"id": 1001,
"code": "COURSE-001",
"name": "高等数学"
}
}调用方收到 HTTP 200 后,根据 errorCode 判断业务结果,再读取成功响应的 data。常见失败边界由稳定错误码表达:
| 错误码类别 | 含义 |
|---|---|
| 参数错误 | target、method 或 JSON 参数格式错误 |
| 未授权 | 缺少、过期或无效的 appClientToken |
| 禁止访问 | token 不属于当前安装、应用未声明方法,或当前用户没有方法权限 |
| 上游失败 | 模块运行时或内部调用链返回失败 |
业务组件只在 SDK 确认 App Gateway 会话失效并清空 client.getSession() 后重新授权。后端业务 CModel
UNAUTHORIZED 不代表登录失效,即使 HTTP 状态为 401 也应保留会话。详见
错误与会话处理。
使用标准 SDK
业务组件不得自行拼接授权头、平台地址或调用 URL,应复用应用启动时创建的标准客户端:
const course = await client.call(
{
type: "module",
bundleId: "course-management",
moduleId: "course-directory",
},
"createCourse",
{
code: "COURSE-001",
name: "高等数学",
teacherId: 123,
tags: ["必修", "一年级"],
},
);客户端由 @baijimu/platform-application-sdk 提供。它读取当前安装会话、发送 Bearer token、解析严格
CModel 响应,并在 401 时清除当前会话。不同部署环境的 appGatewayApiBase 由应用部署配置注入,
不能在业务组件中散落生产域名。
调用前提
一次调用只有同时满足以下条件才会执行:
appClientToken有效且属于 URL 中的installId。- 安装记录处于启用状态,并具有对应运行态应用。
- 当前平台应用版本声明了请求中的
target和method。 - module 或 interface target 已在安装态解析到具体 Runtime 服务,并具有有效的安装态调用身份。
- 当前工作区用户拥有调用该模块方法的权限。
- 目标模块已由当前 Bundle 或其已解析依赖 Bundle 安装物化且方法可用。
App Gateway 通过这些检查并完成安装态解析后,才把方法和请求参数转换为内部运行时调用。前端不需要 了解内部调用信封或模块的后端 HTTP 实现。
新应用统一使用结构化 target 调用入口;/services/{service}/methods/{method} 只服务历史 SDK 2.x
应用。不要把历史 /lowcode3/api、静态站点域名或
其他环境地址拼接为当前应用的 API 地址。