Personal Backend Function
Minimum supported version:
@lovrabet/sdk >= 1.5.3.
About
clientin this page: it refers to theLovrabetClientinstance returned bycreateClient(...). It carries the current app'sappCodeand authentication settings, and exposes the personal function client throughclient.personal.bff.
import { createClient, type LovrabetClient } from "@lovrabet/sdk";
const client: LovrabetClient = createClient({
appCode: "your-app-code",
});The SDK entry point is client.personal.bff.execute. It executes a personal function of the current user in the current app by scriptId and returns the function's business result directly.
const result = await client.personal.bff.execute<ResultType>({
scriptId: 123,
params: { status: "active" },
});Namespace and functions
| Member | Meaning |
|---|---|
client.personal | Namespace for the current user's personal resources. |
client.personal.bff | The Personal Backend Function client. |
client.personal.bff.execute | Executes a function by its personal function ID. |
TypeScript signature:
interface PersonalBffExecuteRequest {
scriptId: number;
params?: Record<string, unknown>;
options?: Omit<RequestInit, "method" | "body">;
}
execute<T = unknown>(
request: PersonalBffExecuteRequest
): Promise<T>;Parameters
| Field | Type | Required | Description |
|---|---|---|---|
scriptId | number | Yes | The personal function ID. Must be a safe integer greater than 0 and belong to the current user and app. |
params | Record<string, unknown> | No | Business parameters passed to the function. When omitted, the request sends no body. |
options | PersonalRequestOptions | No | fetch settings for this request, such as signal and extra headers. The HTTP method and body are controlled by the SDK and cannot be overridden. |
Take scriptId from lovrabet personal-bff list, detail, or the creation result. A function name cannot substitute for the scriptId.
Return value
execute<T>() returns a Promise<T>. The resolved value is exactly the business result of the personal function — no execSuccess, execResult, or any other SDK wrapper.
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);The generic T is a compile-time hint only; nothing is validated at runtime. Pages should still check required fields, nulls, and enum values themselves.
Error handling
When parameters, authentication, or the network request fail, the SDK throws a LovrabetError. HTTP errors returned by the server are preserved as-is — they are never turned into success results.
| Error | Trigger | What to do |
|---|---|---|
PERSONAL_BFF_SCRIPT_ID_INVALID | scriptId is not a safe integer greater than 0. | Re-obtain the ID from list, detail, or the creation result. |
PERSONAL_BFF_AUTH_MODE_UNSUPPORTED | Calling a personal function via OpenAPI. | Use Cookie in the browser; use a Client AK in a Node service. |
| HTTP 400 / 401 / 403 / 500 | Parameters, login state, permissions, or function execution failed. | Read status, code, message, and description, and handle the original error. |
TIMEOUT | The request exceeded the client's timeout. | Check the function's runtime and the request chain before adjusting the timeout. |
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;
}
}Safe calls and undefined
When accommodating an older SDK or a client injected from outside, check the namespace and the method first. Use optional chaining only to read the capability — never to invoke the function.
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" },
});Never write lovrabetClient?.personal?.bff?.execute?.(...). When the method does not exist, that expression silently evaluates to undefined — the request was never sent. Also avoid extracting execute and calling it bare, which loses the method's context.
Browser example: Cookie
In the browser, use the current login Cookie and omit authMode when creating the client. The SDK sends the browser credentials automatically. Never bake Cookies, AccessKeys, SecretKeys, or tokens into frontend code, build variables, or page configuration.
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 example: Client AK
In a Node service using a Client AK, set authMode: "client-ak" explicitly. Read the AccessKey only from the server-side secret store. Personal functions do not support 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" },
});What a Personal Backend Function is
A Personal Backend Function is a lightweight function maintained by the current user within the current app. It fits when a page's multi-step queries, result shaping, or personal workflows belong on the server side — the page just passes parameters and consumes the result.
Personal functions suit personal workflows, feature validation, and light orchestration. Interfaces meant for long-term reuse by many people and maintained centrally should be regular Backend Functions.
Verify before integrating
The SDK only calls personal functions that already exist. Before wiring a page in, verify the same scriptId with the CLI:
lovrabet personal-bff exec \
--id 123 \
--params '{"status":"active"}' \
--format compressOnly after confirming the parameters, returned fields, null cases, and error shapes should you define the TypeScript return type and integrate the page.