Skip to content

天幕运行面 SDK 使用文档

本文说明如何在用户业务后端(Node.js / Java)中接入天幕动态 API自定义 API。SDK 位于 rely-ons,封装换 Token、鉴权头与常用 HTTP 调用,避免每个项目重复写 fetch / HttpClient

路径适用
yc-runtime-sdk(npm)rely-ons/yc-runtime-sdkNode.js ≥ 18(ESM)
yc-runtime-sdkrely-ons/yc-runtime-sdk-javaJava 11+
文档说明
§4 参数获取来源每个参数从哪里拿(平台菜单 / 业务系统 / 自建)
CHANGELOG.md版本变更记录
§12 联调 FAQJSON 列、published_at、天幕调用失败、业务 404

1. 调用链路(推荐)

用户浏览器 → 您的业务后端(BFF)→ 天幕平台运行面 API

         只在这里配置 YC_ACCESS_KEY
         不要把密钥放进前端 / 小程序
  • 动态 API:按数据模型发布,每个操作有独立路径(默认后缀 /list/get/create/update/delete),HTTP 方法可在发布配置中调整。
    基础段:{YC_BASE_URL}/dynamic-api/v1/{projectId}/{modelKey}
    例:http://localhost:8081/yc/dynamic-api/v1/xxx/products/list(分页列表,默认 POST)
  • 自定义 API:按 apiKey 发布,路径形如
    {YC_BASE_URL}/custom-api/v1/{projectId}/{apiKey}

SDK 在启用鉴权时自动完成:

  1. POST .../_auth/token,请求头 X-Access-Key: <接入密钥>
  2. 拿到 accessToken 后,业务请求带 Authorization: Bearer <token>
  3. Token 在内存中缓存,临近过期前自动刷新

2. 平台侧准备(首次接入)

sky-curtain 管理端完成(与是否使用 SDK 无关):

步骤菜单位置说明
数据源服务器管理 → 连接配置指向业务 MySQL 等
动态 API服务器管理 → 数据模型对表发布 list/get/create/put/delete
自定义 API服务器管理 → 自定义 API编排并发布
运行凭证服务器管理 → 服务配置开启鉴权,生成接入密钥ycdk_...

各参数具体从哪里复制、填写,见 §4 配置参数与获取来源

更细的逐步操作可参考:


3. 安装

SDK 支持公开发布(标准明文包,无加密):npm 包名 yc-runtime-sdk,Maven 坐标 team.dream.yc:yc-runtime-sdk

3.0 前置要求

Node.jsJava
运行环境Node ≥ 18JDK ≥ 11
模块格式建议 package.json"type": "module"
获取 SDKnpm install yc-runtime-sdk 或克隆本仓库 file: 安装Maven Central 或 mvn install
业务项目用户自己的 BFF / 后端(非 sky-curtain 前端)同上

3.0.1 从公共仓库安装(推荐,发布后)

Node.js

bash
npm install yc-runtime-sdk
javascript
import { createClientFromEnv } from 'yc-runtime-sdk';

Java(Maven Central 同步后即可,无需额外 repository)

xml
<dependency>
  <groupId>team.dream.yc</groupId>
  <artifactId>yc-runtime-sdk</artifactId>
  <version>1.0.0</version>
</dependency>
java
import team.dream.yc.runtime.YcRuntimeClient;
YcRuntimeClient yc = YcRuntimeClient.fromEnv();

3.0.2 从本仓库本地安装(未发布或开发联调)

若尚未执行公开发布,或需修改 SDK 源码联调,请继续阅读下文 3.1 / 3.2


3.1 Node.js(yc-runtime-sdk

步骤 1:进入业务后端目录

例如演示工程:

bash
cd test-projects/example-1/backend

或您自建的 my-company-api 等项目根目录(该目录下有 package.json)。

步骤 2:按相对路径安装

file: 后面是天幕仓库里 rely-ons/yc-runtime-sdk 相对于当前业务项目的路径,请按实际目录调整:

业务项目位置示例推荐命令
test-projects/example-1/backendnpm install file:../../../rely-ons/yc-runtime-sdk
rely-ons 同级的 my-backend/npm install file:../rely-ons/yc-runtime-sdk
业务项目在仓库外、SDK 在固定目录npm install file:/绝对路径/天幕低代码/rely-ons/yc-runtime-sdk
bash
# 在业务后端根目录执行(示例:example-1)
npm install file:../../../rely-ons/yc-runtime-sdk

使用 pnpm / yarn 时:

bash
pnpm add file:../../../rely-ons/yc-runtime-sdk
# 或
yarn add file:../../../rely-ons/yc-runtime-sdk

步骤 3:确认 package.json

安装成功后应出现依赖项:

json
{
  "type": "module",
  "dependencies": {
    "yc-runtime-sdk": "file:../../../rely-ons/yc-runtime-sdk"
  }
}

步骤 4:可选 — RSA 私钥模式

平台「服务配置」为 CLIENT_RSA 时,需额外安装:

bash
npm install jsonwebtoken

步骤 5:验证能否引用

新建或运行一段脚本(如 scripts/check-sdk.mjs):

javascript
import { createClient } from 'yc-runtime-sdk';

const yc = createClient({
  baseUrl: 'http://localhost:8081/yc',
  projectId: 'test',
  skipAuth: true,
});
console.log('SDK 加载成功', typeof yc.dynamic.list === 'function');
bash
node scripts/check-sdk.mjs
# 输出 SDK 加载成功 true 即表示安装正确

步骤 6:配置环境变量后正式使用

§4 配置参数与获取来源;代码入口:

javascript
import { createClientFromEnv } from 'yc-runtime-sdk';

const yc = createClientFromEnv();

3.2 Java(team.dream.yc:yc-runtime-sdk

步骤 1:将 SDK 安装到本机 Maven 仓库

天幕低代码仓库根目录或任意能访问 rely-ons/yc-runtime-sdk-java 的路径执行:

bash
cd rely-ons/yc-runtime-sdk-java
mvn install -DskipTests

成功结束时日志含 BUILD SUCCESS,本地仓库会有:

text
team.dream.yc : yc-runtime-sdk : 1.0.0

步骤 2:业务项目添加依赖

在业务后端 pom.xml<dependencies> 中增加:

xml
<dependency>
  <groupId>team.dream.yc</groupId>
  <artifactId>yc-runtime-sdk</artifactId>
  <version>1.0.0</version>
</dependency>

若业务工程与 SDK 在同一多模块父工程下,也可改为模块依赖(需自行在父 pom.xmlinstallmodule 引用),一般用户项目独立时用上方的 mvn install 即可。

步骤 3:刷新 IDE / 编译

bash
cd 您的业务Java项目目录
mvn compile

IDEA / Eclipse 执行 Maven Reload。

步骤 4:验证能否引用

java
import team.dream.yc.runtime.YcRuntimeClient;
import team.dream.yc.runtime.YcRuntimeConfig;

public class SdkSmoke {
    public static void main(String[] args) {
        YcRuntimeClient yc = new YcRuntimeClient(
                YcRuntimeConfig.builder()
                        .baseUrl("http://localhost:8081/yc")
                        .projectId("test")
                        .skipAuth(true)
                        .build()
        );
        System.out.println("SDK 加载成功: " + (yc != null));
    }
}

编译运行无 ClassNotFoundException 即安装正确。

步骤 5:配置环境变量后正式使用

java
YcRuntimeClient yc = YcRuntimeClient.fromEnv();

或显式构造:

java
YcRuntimeClient yc = YcRuntimeClient.create(
        "http://localhost:8081/yc",
        "你的项目ID",
        "ycdk_你的接入密钥"
);

3.3 安装后必配项(两种语言相同)

完成安装后,在业务后端配置(.env、系统环境变量或 K8s Secret):

bash
YC_BASE_URL=http://localhost:8081/yc
YC_PROJECT_ID=你的项目ID
YC_ACCESS_KEY=ycdk_平台服务配置中生成的密钥

仅本地、且平台未配密钥试调时可临时:

bash
YC_INVOKE_SKIP_AUTH=1

3.4 从演示工程迁移(可选)

仓库 test-projects/example-1/backend 内原有 yc-client.jsyc-dynamic-client.js 与 SDK 逻辑等价。迁移步骤:

  1. 3.1 安装 yc-runtime-sdk(或 npm install yc-runtime-sdk
  2. 保留现有 .env 变量名(YC_BASE_URLYC_PROJECT_IDYC_ACCESS_KEY
  3. import ... from './yc-dynamic-client.js' 改为 import { createClientFromEnv } from 'yc-runtime-sdk'
  4. yc.dynamic.* / yc.custom.invoke 替换手写 fetch

3.5 常见问题(安装)

问题处理
npm install file:... 报路径找不到检查相对路径是否从业务项目根指向 rely-ons/yc-runtime-sdk
Cannot find package 'yc-runtime-sdk'未执行 npm install yc-runtime-sdk 或本地 file: 路径错误
Java Could not find artifact yc-runtime-sdk未对 rely-ons/yc-runtime-sdk-java 执行 mvn install
修改 SDK 源码后业务未生效Node:在业务目录重新 npm install;Java:对 SDK 再 mvn install 后业务 mvn compile

4. 配置参数与获取来源(必读)

本节说明 SDK 涉及的每一个参数:名称、用途、从哪里获取、填在什么位置。
获取来源分三类:

类型含义示例
平台在天幕 sky-curtain / yc_user_service 上查看或生成YC_PROJECT_IDYC_ACCESS_KEYmodelKey
业务您自己的用户系统、数据库、登录逻辑产生userJwtid、自定义 body 字段
开发本地联调时自行约定,非平台下发YC_INVOKE_SKIP_AUTHcurrentPage

4.1 SDK 连接参数(环境变量 / createClient

在业务后端 .env、K8s Secret 或 createClient({ ... }) 中配置。

参数必填用途获取来源(从哪里拿)填写位置
YC_BASE_URL天幕后端 API 根地址(含 /yc运维 / 部署文档:本地一般为 yc_user_service 启动地址 + 上下文路径。例:application.propertiesserver.port=8081 且接口前缀为 /ychttp://localhost:8081/yc。生产为平台对外域名,如 https://api.your-company.com/yc不是 sky-curtain 前端 Vite 地址(如 localhost:3000)。.envcreateClient.baseUrl
YC_PROJECT_ID标识要调用哪一个天幕应用(项目)sky-curtain 管理端:进入目标应用后,浏览器地址栏 .../project/{项目ID}/... 中这一段(32 位左右字符串)。或 服务器管理 → API 管理 / 服务配置 / 数据模型 任一页面,当前应用即该项目。与「团队 ID」不同。.envcreateClient.projectId
YC_ACCESS_KEY生产建议长期接入密钥,用于向平台换短期 Tokensky-curtain → 服务器管理 → 服务配置:校验方式选「接入密钥(换 Token)」/ PLATFORM_INVOKE 后,点击 「生成接入密钥」;弹窗中 ycdk_ 开头字符串仅展示一次,复制到后端环境变量。不是控制台登录 Token,不是 ycak_ 占位符。.envcreateClient.accessKey
YC_PLATFORM_ACCESS_KEY同上YC_ACCESS_KEY 完全等价(SDK 兼容旧名)。来源同上。二选一即可
YC_INVOKE_SKIP_AUTH跳过运行面鉴权(试调)开发自建:仅在本地联调、且平台未配有效密钥时设为 1。对应平台管理端「试调」时带的跳过头;生产必须关闭.envcreateClient.skipAuth: true
YC_USER_JWT默认业务 JWT(动态 API)业务系统:用户登录后,由您的后端用与平台一致的密钥签发的 JWT(见下表 userJwt)。example-1 中即 auth.jssignToken 结果,密钥来自 .envJWT_SECRET.envcreateClient.userJwt
YC_CLIENT_RSA_PRIVATE_KEYRSA 私钥 PEM(动态 API)sky-curtain → 服务器管理 → 服务配置:校验方式选 「RSA 私钥签 JWT」/ CLIENT_RSA,点击 「生成 RSA 密钥对」私钥仅展示一次,整段 PEM 存入环境变量(可多行或 \n)。公钥已写入平台项目配置。.envcreateClient.rsaPrivateKeyPem
YC_CLIENT_RSA_TTL_SECONDS自签 JWT 有效期(秒)开发自建,默认 600。与平台 Token TTL 无关。.env
YC_DYNAMIC_INVOKE_SKIP_AUTHYC_INVOKE_SKIP_AUTH(example-1 兼容名)开发自建,与上相同。example-1 .env
YC_DYNAMIC_REQUIRE_AUTH业务侧是否要求带凭证调动态 API开发自建:example-1 设为 1 表示必须鉴权;设为 0 且配合 skip 可本地放开。与平台「启用运行时鉴权」开关应一致。example-1 .env

Node createClient / Java YcRuntimeConfig 字段与环境变量一一对应:

代码字段环境变量
baseUrlYC_BASE_URL
projectIdYC_PROJECT_ID
accessKeyYC_ACCESS_KEY / YC_PLATFORM_ACCESS_KEY
skipAuthYC_INVOKE_SKIP_AUTH=1
userJwtYC_USER_JWT
rsaPrivateKeyPemYC_CLIENT_RSA_PRIVATE_KEY
rsaTtlSecondsYC_CLIENT_RSA_TTL_SECONDS

本地最简 .env 示例:

env
YC_BASE_URL=http://localhost:8081/yc
YC_PROJECT_ID=cfeb9dd64869922937499a5e453e6f34
YC_ACCESS_KEY=ycdk_从服务配置「生成接入密钥」复制

# 仅本地试调、未配有效密钥时:
# YC_INVOKE_SKIP_AUTH=1

代码内显式配置(与环境变量二选一):

javascript
import { createClient } from 'yc-runtime-sdk';

const yc = createClient({
  baseUrl: 'http://localhost:8081/yc',   // 来源见上表 YC_BASE_URL
  projectId: 'cfeb9dd64869922937499a5e453e6f34', // 来源见上表 YC_PROJECT_ID
  accessKey: 'ycdk_...',                 // 来源见上表 YC_ACCESS_KEY
  skipAuth: false,
});
java
YcRuntimeClient yc = new YcRuntimeClient(
    YcRuntimeConfig.builder()
        .baseUrl("http://localhost:8081/yc")
        .projectId("cfeb9dd64869922937499a5e453e6f34")
        .accessKey("ycdk_...")
        .build()
);

4.2 平台「服务配置」与鉴权参数对应关系

sky-curtain → 服务器管理 → 服务配置 中的配置,决定您应在后端使用哪类参数:

平台配置项平台位置您在后端应使用的参数说明
启用运行时鉴权服务配置 → 动态 API 鉴权开关有效时须配 YC_ACCESS_KEYuserJwt 或 RSA关闭时运行面可不校验(不推荐生产)
校验方式 = 接入密钥(换 Token)服务配置 → 校验方式 PLATFORM_INVOKEYC_ACCESS_KEYSDK 自动 POST .../_auth/token + Bearer
校验方式 = 项目 JWT服务配置 → PROJECT_JWT + JWT 签名密钥userJwt(每次调用传入或 YC_USER_JWT签名密钥须与业务 JWT_SECRET 完全一致(example-1 的 JWT_SECRET
校验方式 = RSA 私钥签 JWT服务配置 → CLIENT_RSA + 生成密钥对YC_CLIENT_RSA_PRIVATE_KEY私钥来自生成弹窗;Node 需 jsonwebtoken
接入密钥明文服务配置 → 「生成接入密钥」弹窗YC_ACCESS_KEY仅一次;丢失需重新生成
RSA 私钥 PEM服务配置 → 「生成 RSA 密钥对」弹窗YC_CLIENT_RSA_PRIVATE_KEY仅一次
JWT 签名密钥服务配置 → 「JWT 签名密钥」输入框写入业务 JWT_SECRET(非 SDK 环境变量名)用于签发 userJwt,不是 YC_ACCESS_KEY
IP 白名单服务配置 / 对外接入无单独 SDK 变量限制调用平台 API 的服务器出口 IP;在平台填写 BFF 公网 IP

不要混淆:

容易搞错实际来源
天幕控制台登录后的 Token仅用于操作 sky-curtain 管理接口,不能作为 YC_ACCESS_KEYuserJwt 调运行面
ycak_xxxxxxxx 占位符文档示例,无效;须换成服务配置生成的 ycdk_...
换 Token 返回的 accessToken由 SDK 自动换取并缓存,无需手写进 .env

4.3 动态 API 调用参数

参数用途获取来源(从哪里拿)填写位置
modelKey路径中的模型标识,如 .../dynamic-api/v1/{projectId}/{modelKey}sky-curtain → 服务器管理 → 数据模型:对某表发布动态 API 后,一般为表名(如 products)。或 API 管理 列表中「products · 分页列表」里的 products。与连接配置 ID、模型内部 UUID 不同,调用时用 modelKey 字符串yc.dynamic.list('products', ...) 第一个参数
projectId路径中的项目 ID§4.1 YC_PROJECT_ID已由 SDK 从环境变量注入,调用时无需再传
id单条详情 / 更新 / 删除的主键业务数据:列表接口返回的 id 字段,或您业务库主键。新路径约定下通过 ?id= 或请求体 id 传递(不再依赖 .../{id} 路径段;旧写法仍兼容)。yc.dynamic.get('products', id) 等;或 fetch + ?id=
currentPage分页页码业务约定:SDK/平台分页协议字段,默认从 1 开始;非平台某页面复制。body.currentPage
pageSize每页条数业务约定:常用 10200,须 ≤ 平台限制(通常 200)。body.pageSize
params查询条件对象平台发布配置:在 数据模型 → 发布 API 时配置的「查询参数字段」白名单内的键(如 statusname)。键名须与发布时命名策略一致(camelCase / snake_case,example-1 用 YC_DYNAMIC_NAMING 对齐)。body.params
body(create/put)写入字段平台数据模型字段 + 发布允许的写字段;字段名与库表/模型一致,受命名策略影响。yc.dynamic.create / put 的 body

JSON 类型列(如 images 图集):body 中可直接传 JSON 数组或对象,运行面会自动序列化后写入 MySQL JSON 列,无需在 SDK 或业务代码里先 JSON.stringify。详见 数据模型 §5.4。 | userJwt | 动态 API Bearer(PROJECT_JWT 模式) | 业务登录接口:用户登录成功后,您的后端签发的 JWT。example-1:POST /api/login 返回的 data.token,由 JWT_SECRET 签名。须与平台服务配置里 JWT 签名密钥 一致。 | 每次调用第三参,或 YC_USER_JWT |

动态 API 完整 URL 组成(便于核对来源):

text
{YC_BASE_URL}/dynamic-api/v1/{YC_PROJECT_ID}/{modelKey}/{operationSuffix}
     ↑                    ↑              ↑           ↑
  运维/本地8081        地址栏项目ID    API管理/表名   发布配置中的路径后缀

默认后缀(可在发布配置中修改):

操作默认后缀默认方法
分页列表/listPOST
详情/getGET
创建/createPOST
全量更新/updatePUT
删除/deleteDELETE

详情 / 更新 / 删除的主键:GET|PUT|DELETE .../get?id=1 或 body { "id": "1" }

SDK 便捷方法与兼容:

  • yc.dynamic.list / get / create / put / delete 仍使用短路径(如 .../products.../products/{id}),平台运行面会兼容映射到已发布配置。
  • 若你在发布配置里改过路径或方法,或需与 API 管理展示完全一致,请用 yc.dynamic.fetch 并传入发布配置中的后缀与方法,例如:
javascript
await yc.dynamic.fetch('products', '/list', { method: 'POST', body: { currentPage: 1, pageSize: 20, params: {} } });
await yc.dynamic.fetch('products', '/get', { method: 'GET', /* 配合 ?id= 见 dynamicFetch 实现 */ });

数据模型 → 发布 → 接口配置API 管理 中显示的 path、method 为准。


4.4 自定义 API 调用参数

参数用途获取来源(从哪里拿)填写位置
apiKey路径中的 API 标识sky-curtain → 服务器管理 → 自定义 API:列表中的 「API 标识」/ apiKey(如 order_summarygoods-list)。须状态为 已发布;未发布调用会失败。yc.custom.invoke('apiKey', body) 第一个参数
projectId路径中的项目 IDYC_PROJECT_IDSDK 已注入
bodyPOST 请求体平台自定义 API 编排:在编辑器中定义的入参结构;参考该 API 的「试调」请求体或编排说明。无统一固定字段,按每个 apiKey 不同。invoke 第二参数
methodHTTP 方法自定义 API 发布配置 中该 API 的方法(多为 POST);SDK 默认 POST,可选 GET 等。invoke 第三参 opts.method

自定义 API URL:

text
{YC_BASE_URL}/custom-api/v1/{YC_PROJECT_ID}/{apiKey}

鉴权:与动态 API 共用 YC_ACCESS_KEY 换 Token(服务配置统一鉴权开启时)。


4.5 example-1 演示工程参数对照

便于对照 test-projects/example-1/backend/.env

环境变量example-1 中的值从哪来
YC_BASE_URL本地 yc_user_service 默认 http://localhost:8081/yc
YC_PROJECT_ID文档示例 cfeb9dd64869922937499a5e453e6f34,须改成您 sky-curtain 地址栏中的项目 ID
YC_ACCESS_KEY服务配置生成;示例里 ycak_xxxxxxxx 为占位,实际会走 用户登录 JWT
JWT_SECRET业务自建 example1-change-me-in-production,须与服务配置 JWT 签名密钥 一致
YC_USE_DYNAMIC_API业务自建 开关,非 SDK 变量
YC_DYNAMIC_NAMING与平台数据模型发布时的 全局命名策略 一致

验证脚本:cd backend && npm run verify:sdk


4.6 参数获取路径速查(按平台菜单)

text
sky-curtain 登录
  └─ 进入目标应用(记下地址栏 projectId → YC_PROJECT_ID)
       └─ 服务器管理
            ├─ 连接配置        → 数据源(与 SDK 无直接 env,平台内部用)
            ├─ 数据模型        → 发布 API → modelKey(通常=表名)
            ├─ API 管理        → 核对 modelKey、发布状态
            ├─ 自定义 API      → apiKey、body 结构、发布
            └─ 服务配置        → YC_ACCESS_KEY / JWT密钥 / RSA私钥、鉴权方式

yc_user_service 部署地址 + /yc  → YC_BASE_URL

您的业务后端 .env / 配置中心    → 写入上述变量,勿写入前端

5. 鉴权方式说明

各鉴权相关参数在平台的获取位置见 §4.2
SDK 按以下优先级选择凭证(与平台「服务配置」一致):

方式配置适用 API说明
接入密钥 + 平台 TokenYC_ACCESS_KEY动态 + 自定义生产推荐;密钥仅存后端
试调跳过YC_INVOKE_SKIP_AUTH=1动态 + 自定义仅开发;请求带试调头
业务 JWTYC_USER_JWT 或单次 userJwt主要为动态 API平台校验方式为 PROJECT_JWT 时,传用户登录签发的 JWT
RSA 私钥签 JWTYC_CLIENT_RSA_PRIVATE_KEY(Node)动态 API平台为 CLIENT_RSA 时;Java SDK 首版请用 accessKey

开启接入密钥后,换 Token 会先请求:

  • POST {base}/dynamic-api/v1/{projectId}/_auth/token
  • 若失败再尝试 POST {base}/custom-api/v1/{projectId}/_auth/token

统一鉴权开启时,两条路径等效。


6. 动态 API 使用

modelKeyparamsuserJwt 等参数来源见 §4.3
modelKey 与平台发布一致(常见为表名,如 products)。

6.1 Node.js

javascript
import { createClientFromEnv } from 'yc-runtime-sdk';

const yc = createClientFromEnv();

// 分页列表(POST 根路径,body 含 currentPage / pageSize)
const page = await yc.dynamic.list('products', {
  currentPage: 1,
  pageSize: 20,
  params: {}, // 可选:平台配置的查询条件
});

// 单条
const row = await yc.dynamic.get('products', 1);

// 新增
await yc.dynamic.create('products', { name: '商品A', sku: 'SKU001', price: 99 });

// 更新
await yc.dynamic.put('products', 1, { name: '商品A-改' });

// 删除
await yc.dynamic.delete('products', 1);

// 通用请求(自定义 path、方法)
const raw = await yc.dynamic.fetch('products', '/batch', {
  method: 'POST',
  body: { ids: [1, 2, 3] },
});

PROJECT_JWT:用户已登录,把业务 JWT 传给动态调用:

javascript
const list = await yc.dynamic.list('products', { currentPage: 1, pageSize: 10 }, userJwt);

6.2 Java

java
YcRuntimeClient yc = YcRuntimeClient.fromEnv();

Map<String, Object> page = yc.dynamicList("products", Map.of(
        "currentPage", 1,
        "pageSize", 20
));

Object row = yc.dynamicGet("products", 1);

yc.dynamicCreate("products", Map.of("name", "商品A", "sku", "SKU001", "price", 99));
yc.dynamicUpdate("products", 1, Map.of("name", "商品A-改"));
yc.dynamicDelete("products", 1);

// PROJECT_JWT:第四个参数传用户 JWT
yc.dynamicFetch("products", "", "POST", Map.of("currentPage", 1, "pageSize", 10), userJwt);

6.3 列表请求体与路径说明

分页列表默认 POST{base}/dynamic-api/v1/{projectId}/{modelKey}/list

http
POST /yc/dynamic-api/v1/{projectId}/products/list
Content-Type: application/json

{
  "currentPage": 1,
  "pageSize": 20,
  "params": {}
}

其它标准接口(默认路径):

操作方法(默认)路径示例
详情GET.../products/get?id=1
创建POST.../products/create + body
全量更新PUT.../products/update?id=1 + body
删除DELETE.../products/delete?id=1

以上 method、path 均可在发布配置中修改。旧版 POST .../products(根路径)、GET .../products/{id} 仍受平台兼容层支持;SDK 便捷方法 list/get/... 走短路径即可,详见 §4.3

成功时 SDK 返回平台响应里的 data 字段(已解包,不再包含外层 code/message)。

6.4 在 Express 中封装(Node 示例)

javascript
import express from 'express';
import { createClientFromEnv } from 'yc-runtime-sdk';

const app = express();
const yc = createClientFromEnv();

app.get('/api/products', async (req, res) => {
  try {
    const page = await yc.dynamic.list('products', {
      currentPage: Number(req.query.page) || 1,
      pageSize: Number(req.query.size) || 20,
    });
    res.json(page);
  } catch (e) {
    res.status(e.status || 500).json({ message: e.message, code: e.code });
  }
});

7. 自定义 API 使用

apiKeybody 获取来源见 §4.4

7.1 Node.js

javascript
const yc = createClientFromEnv();

const result = await yc.custom.invoke('order_summary', {
  userId: 123,
  dateFrom: '2026-01-01',
});

// 非 POST 时可指定 method
await yc.custom.invoke('export_report', null, { method: 'GET' });

7.2 Java

java
Object result = yc.customInvoke("order_summary", Map.of(
        "userId", 123,
        "dateFrom", "2026-01-01"
));

自定义 API 的请求体、响应结构由平台编排决定,SDK 只负责鉴权与 HTTP。


8. 错误处理

平台统一响应格式:

json
{ "code": 200, "message": "...", "data": { } }

失败时 code !== 200 或 HTTP 非 2xx,SDK 抛出异常:

Node.jsError,附加字段:

  • message:平台返回说明
  • code:业务码
  • status:HTTP 状态
  • platform:原始 JSON(便于排查)
javascript
try {
  await yc.dynamic.list('products', { currentPage: 1, pageSize: 10 });
} catch (e) {
  console.error(e.message, e.code, e.status);
}

JavaYcRuntimeException

java
try {
    yc.dynamicList("products", Map.of("currentPage", 1, "pageSize", 10));
} catch (YcRuntimeException e) {
    System.err.println(e.getMessage() + " code=" + e.getCode());
}

8.1 常见错误对照

现象可能原因处理
缺少鉴权凭证未配 YC_ACCESS_KEY 且未开 YC_INVOKE_SKIP_AUTH在服务配置生成密钥并写入环境变量
接入密钥无效密钥错误或已轮换在平台重新生成并更新后端配置
Token 已过期时钟偏差或缓存异常重启进程;SDK 会自动重新换 Token
401 鉴权凭证无效PROJECT_JWT 时 JWT 密钥与平台不一致对齐 JWT_SECRET 与平台「JWT 签名密钥」
403 IP 不在白名单服务配置启用了 IP 白名单将服务器出口 IP 加入白名单
自定义 API 未发布仅保存未发布在平台点击发布后再调用
动态 API 404modelKey 未发布或拼写错误在 API 管理核对 modelKey
Cannot create a JSON value... binaryJSON 列未按平台规范写入传数组/对象;重启 yc_user_service 并重新发布模型 → 数据模型 FAQ 10.7
字段不能为空: published_at(等)create 显式传了 null 或字段不可写升级运行面 + 可写字段排除该列 → 动态 API FAQ 11.19
天幕动态 API 调用失败: ...运行面校验/ JDBC 错误被 BFF 包装看冒号后原文;控制台试调对比 → 动态 API FAQ 11.20
试调通、SDK 调用仍失败YC_BASE_URL / YC_PROJECT_ID 与试调不一致核对 .env 指向 8081 /yc,不是前端 3000

9. 安全注意事项

  1. YC_ACCESS_KEY 仅放在用户后端,不要写入前端、移动端、公开仓库。
  2. 生产环境关闭 YC_INVOKE_SKIP_AUTH
  3. 平台「服务配置」可配置 IP 白名单、限流;与 Token 为叠加关系。
  4. 终端用户登录态由您的业务系统校验;平台 Token 只表示「该项目后端有权调用运行面」。

10. API 速查

Node.js

方法说明
createClientFromEnv()从环境变量创建客户端
createClient(options)显式配置
yc.dynamic.list(modelKey, body, userJwt?)分页列表
yc.dynamic.get(modelKey, id, userJwt?)查询单条
yc.dynamic.create(modelKey, body, userJwt?)创建
yc.dynamic.put(modelKey, id, body, userJwt?)更新
yc.dynamic.delete(modelKey, id, userJwt?)删除
yc.dynamic.fetch(modelKey, suffix, opts)通用调用
yc.custom.invoke(apiKey, body, opts?)自定义 API

Java

方法说明
YcRuntimeClient.fromEnv()从环境变量创建
YcRuntimeClient.create(baseUrl, projectId, accessKey)快捷构造
dynamicList / dynamicGet / dynamicCreate / dynamicUpdate / dynamicDelete动态 API CRUD
dynamicFetch(modelKey, suffix, method, body, userJwt)通用调用
customInvoke(apiKey, body)自定义 API

11. 与演示工程对照

仓库 test-projects/example-1/backend 内有手写客户端(yc-client.jsyc-dynamic-client.js),逻辑与 SDK 等价。迁移步骤:

  1. 安装 yc-runtime-sdknpm install yc-runtime-sdk
  2. createClientFromEnv() 替换手写 fetch + 换 Token
  3. 保留原有 .env 变量名即可(YC_BASE_URLYC_PROJECT_IDYC_ACCESS_KEY

12. 常见问题(业务后端与动态 API 联调)

本节汇总业务 BFF 通过 SDK 调天幕时的典型问题;平台侧配置细节见 数据模型 FAQ动态 API FAQ

12.1 报错 No static resource api/...(Spring 404)

现象:访问业务后端 GET /api/admin/posts 等返回:

text
No static resource api/admin/posts

原因:这是 业务自有 Controller 路由,不是天幕动态 API。多为 业务后端未重启、未编译进新代码,或 URL 写错。

处理

  1. 重新编译并 重启业务后端(如 xin-lv-server)。
  2. GET /api/health 确认进程已是新版本。
  3. 管理端接口路径以项目内 Controller 为准;数据表 CRUD 仍走 yc.dynamic.create('user_post', ...) 等形式。

与「动态 API 404」不同:后者是 8081 上 modelKey 未发布,见 §8.1。

12.2 是否必须在 BFF 里 JSON.stringify 或去掉 published_at

一般不需要(运行面已升级并重新发布后):

  • JSON 列:SDK dynamic.create body 直接传数组/对象。
  • published_at:create 不传;或传 null(新版运行面视为未传)。

若暂时无法升级天幕,可临时在 BFF 处理,长期应改 平台配置 + 重启 yc_user_service。见 动态 API FAQ 11.22

12.3 发帖成功,App 发现流看不到?

多为 业务审核规则,不是 SDK 故障:

  • create 时 status 为待审(如 2),list 只查已发布(如 status=1)。
  • 须在管理端审核通过并写入 published_at 后才会出现在公开列表。

数据模型字段分工见 数据模型 FAQ 10.10

12.4 联调顺序(推荐)

  1. 平台试调 create/list 通过
  2. SDK 或 curl 经 BFF 环境变量直连天幕验证
  3. 再接业务前端

完整清单:动态 API FAQ 11.21


13. 相关文档

天幕低代码 · 文档由 docs / rely-ons 等目录同步生成