Personal Backend Function(个人函数)
最低支持版本:
@lovrabet/sdk >= 1.5.3。
本文中的
client:指createClient(...)返回的LovrabetClient实例。它保存当前应用的appCode和认证配置,并通过client.personal.bff提供个人函数客户端。
import { createClient, type LovrabetClient } from "@lovrabet/sdk";
const client: LovrabetClient = createClient({
appCode: "your-app-code",
});SDK 调用入口是 client.personal.bff.execute。它按 scriptId 执行当前用户在当前应用中的个人函数,并直接返回函数的业务结果。
const result = await client.personal.bff.execute<ResultType>({
scriptId: 123,
params: { status: "active" },
});命名空间与函数
| 成员 | 含义 |
|---|---|
client.personal | 当前用户的个人资源命名空间。 |
client.personal.bff | Personal Backend Function 客户端。 |
client.personal.bff.execute | 按个人函数 ID 执行函数。 |
TypeScript 签名:
interface PersonalBffExecuteRequest {
scriptId: number;
params?: Record<string, unknown>;
options?: Omit<RequestInit, "method" | "body">;
}
execute<T = unknown>(
request: PersonalBffExecuteRequest
): Promise<T>;入参
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
scriptId | number | 是 | 个人函数 ID。必须是大于 0 的安全整数,并且属于当前用户和当前应用。 |
params | Record<string, unknown> | 否 | 传给个人函数的业务参数。省略时请求不发送 body。 |
options | PersonalRequestOptions | 否 | 本次请求的 fetch 设置,例如 signal 和额外 header。HTTP method 与 body 由 SDK 控制,不能覆盖。 |
scriptId 从 lovrabet personal-bff list、detail 或创建结果中取得。函数名不能代替 scriptId。
返回值
execute<T>() 返回 Promise<T>。解析后的值就是个人函数返回的业务结果,不带 execSuccess、execResult 或其他 SDK 包装。
interface OrderSummary {
total: number;
rows: Array<{ id: number; amount: number }>;
}
const summary = await client.personal.bff.execute<OrderSummary>({
scriptId: 123,
params: { status: "active" },
});
console.log(summary.total);
console.log(summary.rows);泛型 T 只提供编译期类型提示,不会在运行时校验数据。页面仍应检查必需字段、空值和枚举值。
错误处理
参数、认证或网络请求失败时,SDK 抛出 LovrabetError。服务端返回的 HTTP 错误会保留,不会被改成成功结果。
| 错误 | 触发条件 | 处理 |
|---|---|---|
PERSONAL_BFF_SCRIPT_ID_INVALID | scriptId 不是大于 0 的安全整数。 | 从 list、detail 或创建结果重新取得 ID。 |
PERSONAL_BFF_AUTH_MODE_UNSUPPORTED | 使用 OpenAPI 调用个人函数。 | 浏览器使用 Cookie;Node 服务使用 Client AK。 |
| HTTP 400 / 401 / 403 / 500 | 参数、登录状态、权限或函数执行失败。 | 读取 status、code、message 和 description,按原始错误处理。 |
TIMEOUT | 请求超过 client 的超时时间。 | 检查函数耗时和请求链路,再决定是否调整超时。 |
import { LovrabetError } from "@lovrabet/sdk";
try {
const result = await client.personal.bff.execute<OrderSummary>({
scriptId: 123,
params: { status: "active" },
});
} catch (error) {
if (error instanceof LovrabetError) {
console.error(error.status, error.code, error.message, error.description);
} else {
throw error;
}
}安全调用与 undefined
兼容旧版 SDK 或外部注入 client 时,先检查命名空间和方法。可选链只用于读取能力,不要用可选调用执行函数。
const personalBff = lovrabetClient?.personal?.bff;
if (typeof personalBff?.execute !== "function") {
throw new Error("client.personal.bff.execute is not available");
}
const result = await personalBff.execute<OrderSummary>({
scriptId: 123,
params: { status: "active" },
});不要写 lovrabetClient?.personal?.bff?.execute?.(...)。方法不存在时,这种写法会直接得到 undefined,请求根本没有发出。也不要提取 execute 后裸调用,以免丢失方法上下文。
浏览器示例:Cookie
浏览器使用当前登录 Cookie,创建 client 时省略 authMode。SDK 会携带浏览器凭据。不要把 Cookie、AccessKey、SecretKey 或 token 写进前端代码、构建变量和页面配置。
import { createClient } from "@lovrabet/sdk";
const client = createClient({
appCode: "your-app-code",
});
const personalBff = client.personal?.bff;
if (typeof personalBff?.execute !== "function") {
throw new Error("client.personal.bff.execute is not available");
}
const summary = await personalBff.execute<OrderSummary>({
scriptId: 123,
params: { status: "active" },
});Node 示例:Client AK
Node 服务使用 Client AK 时,显式设置 authMode: "client-ak"。AccessKey 只从服务端密钥存储读取。个人函数不支持 OpenAPI。
import { createClient } from "@lovrabet/sdk";
const client = createClient({
appCode: "your-app-code",
authMode: "client-ak",
accessKey: serverSecrets.lovrabetAccessKey,
});
const summary = await client.personal.bff.execute<OrderSummary>({
scriptId: 123,
params: { status: "active" },
});Personal Backend Function 是什么
Personal Backend Function 是当前用户在当前应用中维护的轻量函数。它适合把页面中的多步查询、结果整理或个人工作流放到服务端,页面只传参数并使用结果。
个人函数适合个人工作流、功能验证和轻量编排。需要多人长期复用、统一维护的接口,应使用正式 Backend Function。
调用前验证
SDK 只调用已经存在的个人函数。接入页面前,先用 CLI 验证同一个 scriptId:
lovrabet personal-bff exec \
--id 123 \
--params '{"status":"active"}' \
--format compress确认参数、返回字段、空值和错误形状后,再定义 TypeScript 返回类型并接入页面。