原始接口与 Node.js SDK 封装
Instant API 是每个 dataset 自动具备的数据接口。它提供 WebAPI、OpenAPI、Client API 三种调用模式。本文先说明三种模式的场景、认证和 URL 差异,再以 WebAPI 模式为主讲 9 个核心接口的 curl 原始调用方式,并补充 Node.js SDK 对这些接口的封装关系。
1. 三种调用模式
| 模式 | 适用场景 | 身份语义 | 覆盖范围 |
|---|---|---|---|
| WebAPI | Lovrabet 生成的 Web 页面、微前端子应用、已登录用户在浏览器内访问数据 | 当前登录用户 | 支持 9 个核心 Instant API |
| OpenAPI | 第三方系统、服务端任务、Agent 网关、跨系统集成 | 应用级访问凭证 | 支持部分数据操作,详见 OpenAPI 文档 |
| Client API | CLI、Agent、本地脚本、服务端工具需要以个人身份访问数据 | 个人身份认证 | 支持 9 个核心 Instant API |
选择规则:
- 已经在 Lovrabet 页面或同域浏览器环境中,优先用 WebAPI。
- 外部系统做服务端到服务端集成,优先用 OpenAPI。
- 自动化工具需要代表某个具体用户执行数据操作,优先用 Client API。
2. 认证方式
| 模式 | 认证方式 | 请求头或凭证 | 注意事项 |
|---|---|---|---|
| WebAPI | Cookie 会话认证 | 浏览器自动携带 Cookie;Node.js 可显式传 Cookie Header | 继承当前登录用户权限 |
| OpenAPI | HMAC-SHA256 签名 | X-Time-Stamp、X-App-Code、X-Dataset-Code、X-Token | AccessKey 只能放在服务端,不能进入前端代码 |
| Client API | 个人身份认证 | X-User-AK | 表示具体个人身份,适合 CLI、Agent、脚本和服务端工具 |
3. URL 格式区别
| 模式 | URL 格式 | 请求体格式 | 方法名格式 |
|---|---|---|---|
| WebAPI | /api/{appCode}/{datasetCode}/{method} | 直接传业务参数 | camelCase,例如 getOne、batchCreate |
| OpenAPI | /openapi/data/{method} | { appCode, datasetCode, paramMap };batchCreate 使用 paramList | 部分方法使用 kebab-case,例如 get-one、batch-create |
| Client API | /client/{appCode}/{datasetCode}/{method} | 直接传业务参数 | camelCase,例如 getOne、batchCreate |
4. 本文说明口径
本文的 curl 示例使用 WebAPI 原始接口。它支持 9 个 Instant API,路径规则固定为:
POST {runtimeDomain}/api/{appCode}/{datasetCode}/{method}WebAPI 使用 Cookie 认证,请求体直接传业务参数,不包 appCode、datasetCode 或 paramMap:
export RUNTIME_DOMAIN="https://runtime.lovrabet.com"
export APP_CODE="app_xxx"
export DATASET_CODE="dataset_xxx"
export LOVRABET_COOKIE="your-session-cookie"curl -X POST "$RUNTIME_DOMAIN/api/$APP_CODE/$DATASET_CODE/filter" \
-H "Content-Type: application/json" \
-H "Cookie: $LOVRABET_COOKIE" \
-d '{"currentPage":1,"pageSize":20}'如果运行环境使用个人身份认证的 Client API,路径换成 /client/{appCode}/{datasetCode}/{method},请求体仍然直接传业务参数,认证头使用 X-User-AK:
curl -X POST "$RUNTIME_DOMAIN/client/$APP_CODE/$DATASET_CODE/filter" \
-H "Content-Type: application/json" \
-H "X-User-AK: $LOVRABET_USER_AK" \
-d '{"currentPage":1,"pageSize":20}'OpenAPI 的 URL、认证和请求体与 WebAPI 不同,详细接入不要看本文 curl 示例推断,请参考 OpenAPI。
5. SDK 详细文档
本文只说明 Node.js SDK 方法和原始接口的对应关系,不展开 SDK 的完整安装、配置、认证、错误处理和类型系统。详细用法请参考:
| 文档 | 用途 |
|---|---|
| TypeScript SDK | Node.js / TypeScript SDK 的完整接入、模型配置、认证和方法说明 |
| Java SDK | Java 服务端接入、请求对象、认证和调用示例 |
| OpenAPI | OpenAPI 认证、签名、路径、请求体和完整接口说明 |
6. Node.js SDK 基础封装
Node.js SDK 的模型配置示例:
import { createClient } from "@lovrabet/sdk";
const client = createClient({
appCode: process.env.LOVRABET_APP_CODE,
runtimeDomain: process.env.LOVRABET_RUNTIME_DOMAIN || "https://runtime.lovrabet.com",
cookie: process.env.LOVRABET_COOKIE,
models: [
{
tableName: "orders",
datasetCode: process.env.LOVRABET_DATASET_CODE!,
alias: "orders",
},
],
});
const orders = client.models.orders;SDK 在 Cookie/WebAPI 模式下会把 orders.filter(params) 封装成:
POST /api/{appCode}/{datasetCode}/filter
body: params在 Client API 模式下会封装成:
POST /client/{appCode}/{datasetCode}/filter
body: params7. 接口总表
| API | WebAPI / Client API 路径 | OpenAPI 路径 | Node.js SDK 方法 | 说明 |
|---|---|---|---|---|
filter | /api/{appCode}/{datasetCode}/filter 或 /client/{appCode}/{datasetCode}/filter | /openapi/data/filter | client.models.<alias>.filter(params) | 列表、搜索、筛选、分页 |
aggregate | /api/{appCode}/{datasetCode}/aggregate 或 /client/{appCode}/{datasetCode}/aggregate | /openapi/data/aggregate | client.models.<alias>.aggregate(params) | 分组统计、求和、计数、平均值 |
getOne | /api/{appCode}/{datasetCode}/getOne 或 /client/{appCode}/{datasetCode}/getOne | /openapi/data/get-one | client.models.<alias>.getOne(id) | 按 ID 读取单条记录 |
create | /api/{appCode}/{datasetCode}/create 或 /client/{appCode}/{datasetCode}/create | /openapi/data/create | client.models.<alias>.create(data) | 新增单条记录 |
batchCreate | /api/{appCode}/{datasetCode}/batchCreate 或 /client/{appCode}/{datasetCode}/batchCreate | /openapi/data/batch-create | client.models.<alias>.batchCreate(items) | 批量新增记录 |
update | /api/{appCode}/{datasetCode}/update 或 /client/{appCode}/{datasetCode}/update | /openapi/data/update | client.models.<alias>.update(id, data) 或 update({ id, ...data }) | 更新单条或批量记录 |
delete | /api/{appCode}/{datasetCode}/delete 或 /client/{appCode}/{datasetCode}/delete | 不支持 | client.models.<alias>.delete(id) 或 delete({ id }) | 删除单条或批量记录 |
getSelectOptions | /api/{appCode}/{datasetCode}/getSelectOptions 或 /client/{appCode}/{datasetCode}/getSelectOptions | 不支持 | client.models.<alias>.getSelectOptions(params) | 获取下拉选项 |
excelExport | /api/{appCode}/{datasetCode}/excelExport 或 /client/{appCode}/{datasetCode}/excelExport | 不支持 | client.models.<alias>.excelExport(params) | 导出 Excel 文件 |
OpenAPI 请求体与 WebAPI / Client API 不同。OpenAPI 的业务参数放在 paramMap,batchCreate 使用 paramList;详细签名和请求体请参考 OpenAPI。
8. 9 个 API 详情
8.1 filter
filter 用于查询一批记录,支持条件、字段选择、排序和分页。
curl -X POST "$RUNTIME_DOMAIN/api/$APP_CODE/$DATASET_CODE/filter" \
-H "Content-Type: application/json" \
-H "Cookie: $LOVRABET_COOKIE" \
-d '{
"where": {
"$and": [
{ "status": { "$eq": "paid" } },
{ "amount": { "$gte": 100 } }
]
},
"select": ["id", "orderNo", "status", "amount", "createdAt"],
"orderBy": [{ "createdAt": "desc" }],
"currentPage": 1,
"pageSize": 20
}'SDK 封装:
const result = await orders.filter({
where: {
$and: [
{ status: { $eq: "paid" } },
{ amount: { $gte: 100 } },
],
},
select: ["id", "orderNo", "status", "amount", "createdAt"],
orderBy: [{ createdAt: "desc" }],
currentPage: 1,
pageSize: 20,
});返回值是分页结构,核心字段为 tableData、paging、tableColumns。
8.2 aggregate
aggregate 用于聚合统计,支持 SUM、COUNT、AVG,也支持 groupBy、having 和 orderBy。
curl -X POST "$RUNTIME_DOMAIN/api/$APP_CODE/$DATASET_CODE/aggregate" \
-H "Content-Type: application/json" \
-H "Cookie: $LOVRABET_COOKIE" \
-d '{
"select": ["status"],
"aggregate": [
{ "type": "COUNT", "field": "id", "alias": "order_count" },
{ "type": "SUM", "field": "amount", "alias": "total_amount", "round": true, "precision": 2 }
],
"where": { "createdAt": { "$gte": "2026-01-01" } },
"groupBy": ["status"],
"having": [
{ "columnName": "total_amount", "condition": { "$gte": 10000 } }
],
"orderBy": [{ "total_amount": "desc" }],
"currentPage": 1,
"pageSize": 20
}'SDK 封装:
const result = await orders.aggregate({
select: ["status"],
aggregate: [
{ type: "COUNT", field: "id", alias: "order_count" },
{ type: "SUM", field: "amount", alias: "total_amount", round: true, precision: 2 },
],
where: { createdAt: { $gte: "2026-01-01" } },
groupBy: ["status"],
having: [
{ columnName: "total_amount", condition: { $gte: 10000 } },
],
orderBy: [{ total_amount: "desc" }],
currentPage: 1,
pageSize: 20,
});返回值同样是分页结构,tableData 中每一项是聚合结果。
8.3 getOne
getOne 用于按记录 ID 读取单条详情。
curl -X POST "$RUNTIME_DOMAIN/api/$APP_CODE/$DATASET_CODE/getOne" \
-H "Content-Type: application/json" \
-H "Cookie: $LOVRABET_COOKIE" \
-d '{"id":"order_001"}'SDK 封装:
const order = await orders.getOne("order_001");
const sameOrder = await orders.getOne({ id: "order_001" });已知 ID 时直接用 getOne,不要用 filter 模拟单条详情。
8.4 create
create 用于新增一条记录,请求体就是要写入的业务字段。
curl -X POST "$RUNTIME_DOMAIN/api/$APP_CODE/$DATASET_CODE/create" \
-H "Content-Type: application/json" \
-H "Cookie: $LOVRABET_COOKIE" \
-d '{
"customerId": "customer_001",
"amount": 199.9,
"status": "pending"
}'SDK 封装:
const created = await orders.create({
customerId: "customer_001",
amount: 199.9,
status: "pending",
});默认值、唯一性、状态机等统一规则应放到 create 的 Before Hook 中。
8.5 batchCreate
batchCreate 用于一次新增多条记录。WebAPI 原始接口的请求体是数组,不需要包成 { items: [...] }。
curl -X POST "$RUNTIME_DOMAIN/api/$APP_CODE/$DATASET_CODE/batchCreate" \
-H "Content-Type: application/json" \
-H "Cookie: $LOVRABET_COOKIE" \
-d '[
{ "customerId": "customer_001", "amount": 100, "status": "pending" },
{ "customerId": "customer_002", "amount": 200, "status": "pending" }
]'SDK 封装:
const createdRows = await orders.batchCreate([
{ customerId: "customer_001", amount: 100, status: "pending" },
{ customerId: "customer_002", amount: 200, status: "pending" },
]);SDK 会校验入参必须是非空数组,且最多 1000 条。
8.6 update
update 用于更新单条或多条记录。请求体必须包含 id,其他字段是待更新内容。
curl -X POST "$RUNTIME_DOMAIN/api/$APP_CODE/$DATASET_CODE/update" \
-H "Content-Type: application/json" \
-H "Cookie: $LOVRABET_COOKIE" \
-d '{
"id": "order_001",
"status": "paid",
"paidAt": "2026-04-23T10:00:00Z"
}'批量更新时把 id 传成数组:
curl -X POST "$RUNTIME_DOMAIN/api/$APP_CODE/$DATASET_CODE/update" \
-H "Content-Type: application/json" \
-H "Cookie: $LOVRABET_COOKIE" \
-d '{
"id": ["order_001", "order_002"],
"status": "archived"
}'SDK 封装:
const updated = await orders.update({
id: "order_001",
status: "paid",
paidAt: "2026-04-23T10:00:00Z",
});
const updatedBatch = await orders.update(
["order_001", "order_002"],
{ status: "archived" },
);SDK 会校验批量更新最多 1000 条。
8.7 delete
delete 用于删除单条或多条记录。删除是高风险写操作,自动化脚本中要显式确认 dataset 和 id。
curl -X POST "$RUNTIME_DOMAIN/api/$APP_CODE/$DATASET_CODE/delete" \
-H "Content-Type: application/json" \
-H "Cookie: $LOVRABET_COOKIE" \
-d '{"id":"order_001"}'批量删除:
curl -X POST "$RUNTIME_DOMAIN/api/$APP_CODE/$DATASET_CODE/delete" \
-H "Content-Type: application/json" \
-H "Cookie: $LOVRABET_COOKIE" \
-d '{"id":["order_001","order_002"]}'SDK 封装:
await orders.delete("order_001");
await orders.delete({ id: ["order_001", "order_002"] });SDK 会校验批量删除最多 1000 条。OpenAPI 模式不支持 delete,需要使用 WebAPI 或 Client API 模式。
8.8 getSelectOptions
getSelectOptions 用于把 dataset 数据转成前端组件常用的 { label, value } 选项数组。
curl -X POST "$RUNTIME_DOMAIN/api/$APP_CODE/$DATASET_CODE/getSelectOptions" \
-H "Content-Type: application/json" \
-H "Cookie: $LOVRABET_COOKIE" \
-d '{
"code": "id",
"label": "name"
}'SDK 封装:
const options = await orders.getSelectOptions({
code: "id",
label: "name",
});它适合 Select、Radio、Checkbox、筛选器和联想输入。OpenAPI 模式不支持 getSelectOptions,需要使用 WebAPI 或 Client API 模式。
8.9 excelExport
excelExport 用于把 dataset 查询结果导出成 Excel 文件,通常返回可下载的文件 URL。
curl -X POST "$RUNTIME_DOMAIN/api/$APP_CODE/$DATASET_CODE/excelExport" \
-H "Content-Type: application/json" \
-H "Cookie: $LOVRABET_COOKIE" \
-d '{
"where": { "status": { "$eq": "paid" } },
"select": ["id", "orderNo", "status", "amount"],
"orderBy": [{ "createdAt": "desc" }]
}'SDK 封装:
const fileUrl = await orders.excelExport({
where: { status: { $eq: "paid" } },
select: ["id", "orderNo", "status", "amount"],
orderBy: [{ createdAt: "desc" }],
});导出条件应复用页面 filter 条件,避免页面查询和导出口径不一致。OpenAPI 模式不支持 excelExport,需要使用 WebAPI 或 Client API 模式。