API 参考
本文档提供 Lovrabet OpenAPI 所有接口的完整参考,包括 SDK 用法和底层 HTTP 规范。
基础信息
环境地址
| 环境 | 域名 |
|---|---|
| 生产环境 | https://runtime.lovrabet.com |
请求规范
- 请求方法: 所有接口统一使用
POST - 内容类型:
application/json - 字符编码:
UTF-8 - 超时设置: 建议设置 30 秒超时
认证方式
所有请求需要在 HTTP Header 中包含以下认证信息:
| Header 名称 | 说明 | 示例 |
|---|---|---|
| X-Time-Stamp | 时间戳(毫秒) | 1758903130713 |
| X-App-Code | 应用编码 | app-c2dd52a2 |
| X-Dataset-Code | 数据集编码(部分接口需要) | 0fefba76fe29...ff |
| X-Token | 签名 Token | jdqqGtzecF2I6FIW... |
SDK 会自动添加所有必需的请求头,无需手动处理。
OpenAPI 接口列表
完整接口清单
以下是 Lovrabet OpenAPI 提供的所有接口及其详细信息:
| 接口名称 | HTTP 方法 | 完整 URL 路径 | SDK 方法 | 功能说明 |
|---|---|---|---|---|
| 批量查询数据 | POST | /openapi/data/get-list | getList(params?, sortList?) | 分页查询数据,支持筛选、排序 |
| 查询单条数据 | POST | /openapi/data/get-one | getOne(id) | 根据 ID 获取单条数据详情 |
| 创建数据 | POST | /openapi/data/create | create(data) | 创建新的数据记录 |
| 更新数据 | POST | /openapi/data/update | update(id, data) | 更新已有数据记录 |
OpenAPI 目前暂不支持 delete()、getSelectOptions() 和 excelExport() 操作。如需使用这些功能,请使用基于 Cookie 认证的 WebAPI 模式。
请求参数规范
所有 OpenAPI 接口的请求体都遵循以下结构:
{
appCode: string; // 应用编码(所有接口必需)
datasetCode: string; // 数据集编码(所有数据操作接口都需要)
paramMap: { // 业务参数对象
// 具体参数根据不同接口而定
}
}
认证信息传递方式:
- OpenAPI 的认证信息(不在请求体中),而是通过 HTTP Headers 传递:
X-Time-Stamp: 时间戳X-App-Code: 应用编码X-Dataset-Code: 数据集编码X-Token: 签名 Token
- SDK 会自动处理这些 Headers,开发者无需手动添加
各接口参数详解
1. 批量查询数据 (getList)
URL: POST /openapi/data/get-list
请求体参数:
{
appCode: string;
datasetCode: string;
paramMap: {
currentPage?: number; // 当前页码,从 1 开始
pageSize?: number; // 每页条数
ytSortList?: SortList; // 排序配置(通过 SDK 的 sortList 参数自动添加)
[key: string]: any; // 其他查询条件(根据数据集字段)
}
}
参数说明:
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
appCode | string | ✅ 是 | - | 应用编码 |
datasetCode | string | ✅ 是 | - | 数据集编码 |
paramMap.currentPage | number | ❌ 否 | 1 | 当前页码,从 1 开始 |
paramMap.pageSize | number | ❌ 否 | 20 | 每页记录数,最大 100 |
paramMap.ytSortList | SortList | ❌ 否 | - | 排序配置数组,由 SDK 的 sortList 参数自动生成 |
paramMap.[字段名] | any | ❌ 否 | - | 其他查询条件,根据数据集实际字段定义 |
查询条件示例:
根据数据集的不同字段,可以使用以下查询模式:
{
// 精确匹配
status: "active",
customer_type: "vip",
// 模糊查询(字段名加 _like 后缀)
name_like: "张",
// 范围查询(字段名加 _start/_end 后缀)
create_time_start: "2024-01-01",
create_time_end: "2024-12-31",
amount_start: 1000,
amount_end: 5000,
// IN 查询(字段名加 _in 后缀,值为数组)
status_in: ["active", "pending"],
// IS NULL 查询(字段名加 _is_null 后缀)
deleted_at_is_null: true,
}
排序功能 (ytSortList):
OpenAPI 使用 ytSortList 字段进行排序,通过 SDK 的 sortList 参数传入:
import { SortOrder } from "@lovrabet/sdk";
// SDK 调用方式(推荐)
const result = await client.models.users.filter(
{ currentPage: 1, pageSize: 20 },
[
{ priority: SortOrder.DESC }, // 优先级降序
{ createTime: SortOrder.DESC }, // 创建时间降序
{ name: SortOrder.ASC }, // 名称升序
]
);
// SDK 会自动将 sortList 转换为 ytSortList 字段放到 paramMap 中
// 实际请求体: { appCode, datasetCode, paramMap: { ytSortList: [...] } }
- OpenAPI 只支持通过
ytSortList字段排序 - 使用 SDK 时,通过
getList()方法的第二个参数sortList传入排序配置 - SDK 会自动将
sortList转换为ytSortList格式
响应数据 (data 字段):
{
paging: {
pageSize: number; // 每页记录数
totalCount: number; // 总记录数
currentPage: number; // 当前页码
}
tableData: Array<T>; // 数据列表数组
tableColumns: Array<{
title: string; // 列标题
dataIndex: string; // 字段名
}>;
}
2. 查询单条数据 (getOne)
URL: POST /openapi/data/get-one
请求体参数:
{
appCode: string;
datasetCode: string;
paramMap: {
id: string | number; // 记录 ID
}
}
参数说明:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
appCode | string | ✅ 是 | 应用编码 |
datasetCode | string | ✅ 是 | 数据集编码 |
paramMap.id | string/number | ✅ 是 | 要查询的记录 ID |
响应数据 (data 字段):
{
id: string | number; // 记录 ID
[key: string]: any; // 其他字段根据数据集定义
}
3. 创建数据 (create)
URL: POST /openapi/data/create
请求体参数:
{
appCode: string;
datasetCode: string;
paramMap: {
[key: string]: any; // 要创建的数据字段
}
}
参数说明:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
appCode | string | ✅ 是 | 应用编码 |
datasetCode | string | ✅ 是 | 数据集编码 |
paramMap.[字段名] | any | 根据字段定义 | 要创建的数据,字段和必填性根据数据集定义 |
注意事项:
- 系统字段(如
id,gmt_create,gmt_modified)会自动生成,无需传入 - 必填字段必须提供,否则会返回参数错误
- 字段类型需要与数据集定义一致
响应数据 (data 字段):
{
id: string | number; // 新创建记录的 ID
[key: string]: any; // 完整的记录数据(包括自动生成的字段)
}
4. 更新数据 (update)
URL: POST /openapi/data/update
请求体参数:
{
appCode: string;
datasetCode: string;
paramMap: {
id: string | number; // 要更新的记录 ID
[key: string]: any; // 要更新的字段
}
}
参数说明:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
appCode | string | ✅ 是 | 应用编码 |
datasetCode | string | ✅ 是 | 数据集编码 |
paramMap.id | string/number | ✅ 是 | 要更新的记录 ID |
paramMap.[字段名] | any | ❌ 否 | 要更新的字段,只需传入需要更新的字段即可(部分更新) |
注意事项:
- 支持部分更新,只需传入要修改的字段
gmt_modified字段会自动更新- 不能修改
id和gmt_create字段
响应数据 (data 字段):
{
id: string | number; // 记录 ID
[key: string]: any; // 完整的更新后记录数据
}
响应结构
通用响应格式
所有接口响应都包含以下顶层字段(由平台网关返回):
{
success: boolean; // 请求是否成功
msg: string; // 响应消息
data: any; // 响应数据
errorCode?: number; // 错误码(失败时返回)
errorMsg?: string; // 错误信息(失败时返回)
}
getList 响应的固定字段
getList 接口的 data 字段包含以下三个固定字段(SDK 返回结构与平台一致):
{
paging: {
// 【固定字段】分页信息
pageSize: number; // 每页记录数
totalCount: number; // 总记录数
currentPage: number; // 当前页码
}
tableData: Array<T>; // 【固定字段】数据列表数组
tableColumns: Array<{
// 【固定字段】表格列定义
title: string; // 列标题
dataIndex: string; // 字段名
}>;
}
SDK 使用
创建客户端
import { createClient } from "@lovrabet/sdk";
const client = createClient({
appCode: "your-app-code",
accessKey: process.env.LOVRABET_ACCESS_KEY,
models: {
users: {
tableName: "users",
datasetCode: "your-dataset-code",
},
},
});
SDK 方法列表
每个模型实例都提供以下方法:
| 方法 | 说明 | 对应 API |
|---|---|---|
getList(params?) | 批量查询数据 | /openapi/data/get-list |
getOne(id) | 查询单条数据 | /openapi/data/get-one |
create(data) | 新增单条数据 | /openapi/data/create |
update(id, data) | 更新单条数据 | /openapi/data/update |
API 详细说明
1. 批量查询数据(getList)
分页查询数据集中的数据,支持条件筛选、排序等功能。
SDK 用法
基础查询:
const response = await client.models.users.filter({
currentPage: 1,
pageSize: 20,
});
// 解构响应
const { paging, tableData, tableColumns } = response;
console.log("总条数:", paging.totalCount);
console.log("当前页:", paging.currentPage);
console.log("数据:", tableData);
console.log("列定义:", tableColumns);
条件查询:
const response = await client.models.users.filter({
currentPage: 1,
pageSize: 20,
// 查询条件(根据数据集实际字段)
status: "active",
customer_type: "vip",
});
分页遍历:
async function getAllUsers() {
const allUsers = [];
let currentPage = 1;
const pageSize = 50;
while (true) {
const { paging, tableData } = await client.models.users.filter({
currentPage,
pageSize,
});
allUsers.push(...tableData);
// 判断是否还有更多数据
if (currentPage * pageSize >= paging.totalCount) {
break;
}
currentPage++;
// 避免请求过快
await new Promise((resolve) => setTimeout(resolve, 100));
}
return allUsers;
}
HTTP 规范
接口地址: POST /openapi/data/get-list
请求头:
X-Time-Stamp: {timestamp}
X-App-Code: {appCode}
X-Dataset-Code: {datasetCode}
X-Token: {token}
请求体:
{
"appCode": "app-c2dd52a2",
"datasetCode": "0fefba76fe29440194841f4825df53ff",
"paramMap": {
"pageSize": 10,
"currentPage": 1,
"status": "active",
"customer_type": "vip",
"create_time_start": "2024-01-01",
"create_time_end": "2024-12-31"
}
}
带排序的请求体示例:
{
"appCode": "app-c2dd52a2",
"datasetCode": "0fefba76fe29440194841f4825df53ff",
"paramMap": {
"pageSize": 10,
"currentPage": 1,
"ytSortList": [{ "gmt_create": "desc" }, { "id": "asc" }],
"status": "active"
}
}
响应结构说明:
data 字段下包含三个固定字段:
paging- 分页信息(固定字段)tableData- 数据列表(固定字段)tableColumns- 表格列定义(固定字段)
响应示例:
{
"success": true,
"msg": "查询成功",
"data": {
"paging": {
"pageSize": 10,
"totalCount": 156,
"currentPage": 1
},
"tableData": [
{
"id": "123",
"customer_name": "示例客户",
"customer_type": "vip",
"contact_person": "张三",
"phone": "13800138000",
"email": "example@example.com",
"address": "北京市朝阳区",
"status": "active",
"credit_level": "A",
"gmt_create": "2024-01-15 10:30:00",
"gmt_modified": "2024-03-20 14:25:00"
}
],
"tableColumns": [
{
"title": "客户名称",
"dataIndex": "customer_name"
},
{
"title": "客户类型",
"dataIndex": "customer_type"
},
{
"title": "联系人",
"dataIndex": "contact_person"
}
]
}
}
查询参数详解
分页参数:
| 参数 | 类型 | 必须 | 默认值 | 说明 |
|---|---|---|---|---|
pageSize | number | 否 | 10 | 每页记录数,最大 100 |
currentPage | number | 否 | 1 | 当前页码,从 1 开始 |
排序参数:
| 参数 | 类型 | 必须 | 说明 |
|---|---|---|---|
ytSortList | Array | 否 | 排序配置数组,格式: [{ "字段名": "asc/desc" }] |
使用 SDK 时通过 getList() 的第二个参数传入 sortList,SDK 会自动转换为 ytSortList 字段。
详见上方"排序功能"章节的说明。
条件查询:
条件查询参数根据不同数据集的字段而定,常见的查询方式:
{
// 精确匹配
field_name: "value",
// 模糊查询(部分字段支持)
field_name_like: "value",
// 范围查询
field_name_start: "value1",
field_name_end: "value2",
// IN 查询(部分字段支持)
field_name_in: ["value1", "value2"],
// NULL 判断(部分字段支持)
field_name_is_null: true,
}
2. 查询单条数据(getOne)
根据唯一标识查询单条详细数据。
SDK 用法
// 查询单条数据
const user = await client.models.users.getOne("user-id");
console.log(user);
// 返回单个对象,包含该记录的所有字段
// 或者使用对象参数
const user = await client.models.users.getOne({
id: 14,
});
HTTP 规范
接口地址: POST /openapi/data/get-one
请求头:
X-Time-Stamp: {timestamp}
X-App-Code: {appCode}
X-Dataset-Code: {datasetCode}
X-Token: {token}
请求体:
{
"appCode": "app-c2dd52a2",
"datasetCode": "0fefba76fe29440194841f4825df53ff",
"paramMap": {
"id": 14
}
}
响应示例:
{
"success": true,
"msg": "查询成功",
"data": {
"id": 14,
"customer_name": "示例客户",
"customer_type": "vip",
"contact_person": "张三",
"phone": "13800138000",
"email": "example@example.com",
"address": "北京市朝阳区XX路XX号",
"status": "active",
"credit_level": "A",
"credit_amount": 100000.0,
"used_amount": 35000.0,
"available_amount": 65000.0,
"contract_start": "2024-01-01",
"contract_end": "2024-12-31",
"sales_person": "王经理",
"department": "华北销售部",
"gmt_create": "2024-01-15 10:30:00",
"gmt_modified": "2024-03-20 14:25:00",
"remark": "重要VIP客户,需重点维护"
}
}
3. 新增单条数据(create)
创建一条新的数据记录。
SDK 用法
// 新增客户信息
const newCustomer = await client.models.users.create({
customer_name: "新客户公司",
customer_type: "enterprise",
contact_person: "李经理",
phone: "13900139000",
email: "contact@newcustomer.com",
address: "上海市浦东新区",
status: "active",
credit_level: "B",
});
console.log("新客户 ID:", newCustomer.id);
console.log("创建时间:", newCustomer.gmt_create);
HTTP 规范
接口地址: POST /openapi/data/create
请求头:
X-Time-Stamp: {timestamp}
X-App-Code: {appCode}
X-Dataset-Code: {datasetCode}
X-Token: {token}
请求体:
{
"appCode": "app-c2dd52a2",
"datasetCode": "0fefba76fe29440194841f4825df53ff",
"paramMap": {
"customer_name": "新客户公司",
"customer_type": "enterprise",
"contact_person": "李经理",
"phone": "13900139000",
"email": "contact@newcustomer.com",
"address": "上海市浦东新区",
"status": "active",
"credit_level": "B"
}
}
响应示例:
{
"success": true,
"msg": "创建成功",
"data": {
"id": 158,
"customer_name": "新客户公司",
"customer_type": "enterprise",
"contact_person": "李经理",
"phone": "13900139000",
"email": "contact@newcustomer.com",
"address": "上海市浦东新区",
"status": "active",
"credit_level": "B",
"credit_amount": 0.0,
"used_amount": 0.0,
"available_amount": 0.0,
"gmt_create": "2025-10-10 15:30:00",
"gmt_modified": "2025-10-10 15:30:00"
}
}
4. 更新单条数据(update)
根据 ID 更新已有数据记录的部分或全部字段。
SDK 用法
// 更新客户信息
const updatedCustomer = await client.models.users.update(158, {
customer_type: "vip",
credit_level: "A",
credit_amount: 200000.0,
remark: "升级为 VIP 客户,提升信用额度",
});
console.log("更新后的客户类型:", updatedCustomer.customer_type);
console.log("更新时间:", updatedCustomer.gmt_modified);
批量更新示例:
// 批量更新多个客户的状态
const customerIds = [101, 102, 103];
const updateResults = await Promise.all(
customerIds.map((id) =>
client.models.users.update(id, {
status: "inactive",
remark: "批量停用",
})
)
);
console.log(`成功更新 ${updateResults.length} 个客户`);
HTTP 规范
接口地址: POST /openapi/data/update
请求头:
X-Time-Stamp: {timestamp}
X-App-Code: {appCode}
X-Dataset-Code: {datasetCode}
X-Token: {token}
请求体:
{
"appCode": "app-c2dd52a2",
"datasetCode": "0fefba76fe29440194841f4825df53ff",
"paramMap": {
"id": 158,
"customer_type": "vip",
"credit_level": "A",
"credit_amount": 200000.0,
"remark": "升级为 VIP 客户,提升信用额度"
}
}
响应示例:
{
"success": true,
"msg": "更新成功",
"data": {
"id": 158,
"customer_name": "新客户公司",
"customer_type": "vip",
"contact_person": "李经理",
"phone": "13900139000",
"email": "contact@newcustomer.com",
"address": "上海市浦东新区",
"status": "active",
"credit_level": "A",
"credit_amount": 200000.0,
"used_amount": 0.0,
"available_amount": 200000.0,
"gmt_create": "2025-10-10 15:30:00",
"gmt_modified": "2025-10-10 16:45:00",
"remark": "升级为 VIP 客户,提升信用额度"
}
}
OpenAPI 目前不提供物理删除接口。如需删除数据,建议使用"软删除"方式,即通过 update() 方法更新状态字段:
// 推荐:使用软删除(更新状态为 deleted)
await client.models.users.update(158, {
status: "deleted",
deleted_at: new Date().toISOString(),
remark: "客户要求删除数据",
});
console.log("客户已标记为删除");
软删除的优势:
- ✅ 数据可恢复
- ✅ 保留操作记录
- ✅ 符合数据合规要求
错误处理
错误码说明
当请求失败时,success 字段为 false,并返回相应的错误码和错误信息。
| 错误码 | 说明 | 解决方案 |
|---|---|---|
| 1001 | 参数错误 | 检查请求参数是否完整、格式是否正确 |
| 1002 | 签名验证失败 | 检查 Access Key、签名算法、时间戳 |
| 1003 | 时间戳过期 | Token 已过期(10 分钟),重新生成 |
| 1004 | 应用不存在 | 检查 App Code 是否正确 |
| 1005 | 数据集不存在 | 检查 Dataset Code 是否正确 |
| 1006 | 无访问权限 | 确认应用是否有该数据集的访问权限 |
| 2001 | 查询超时 | 优化查询条件,减少数据量 |
| 2002 | 数据不存在 | 检查查询条件或 ID 是否正确 |
| 3001 | 服务器内部错误 | 联系技术支持 |
| 4001 | 请求频率超限 | 降低请求频率,实施限流策略 |
错误响应示例
{
"success": false,
"msg": null,
"data": null,
"errorCode": 1002,
"errorMsg": "签名验证失败,请检查 Token 生成算法"
}
SDK 错误处理
import { LovrabetError } from "@lovrabet/sdk";
try {
const users = await client.models.users.filter();
} catch (error) {
if (error instanceof LovrabetError) {
console.error("错误码:", error.statusCode);
console.error("错误信息:", error.message);
console.error("错误详情:", error.details);
// 根据错误码处理
switch (error.statusCode) {
case 1002:
console.error("签名验证失败,请检查 Access Key");
break;
case 1003:
console.error("Token 已过期,需要刷新");
break;
case 1006:
console.error("无权访问该数据集");
break;
default:
console.error("其他错误");
}
} else {
console.error("未知错误:", error);
}
}
高级用法
1. TypeScript 类型支持
import { createClient, ListResponse } from "@lovrabet/sdk";
// 定义数据类型
interface User {
id: string;
name: string;
email: string;
status: "active" | "inactive";
gmt_create: string;
}
const client = createClient({
// ... 配置
});
// 类型化查询
const response: ListResponse<User> = await client.models.users.filter();
response.tableData.forEach((user: User) => {
console.log(user.name, user.email);
});
2. 多模型配置
const client = createClient({
appCode: "your-app-code",
accessKey: process.env.LOVRABET_ACCESS_KEY,
models: {
users: {
tableName: "users",
datasetCode: "dataset-001",
},
orders: {
tableName: "orders",
datasetCode: "dataset-002",
},
products: {
tableName: "products",
datasetCode: "dataset-003",
},
},
});
// 使用不同的模型
const users = await client.models.users.filter();
const orders = await client.models.orders.filter();
const products = await client.models.products.filter();
3. 响应数据转换
const response = await client.models.users.filter();
// 提取纯数据数组
const users = response.tableData;
// 提取列定义(用于动态构建表格 UI)
const columns = response.tableColumns.map((col) => ({
title: col.title,
field: col.dataIndex,
}));
// 分页信息
const { totalCount, currentPage, pageSize } = response.paging;
const totalPages = Math.ceil(totalCount / pageSize);
4. 请求拦截和日志
import { createClient } from "@lovrabet/sdk";
const client = createClient({
appCode: "your-app-code",
accessKey: process.env.LOVRABET_ACCESS_KEY,
models: {
/* ... */
},
});
// 包装请求方法添加日志
const originalGetList = client.models.users.getList.bind(client.models.users);
client.models.users.getList = async function (params) {
console.log("请求参数:", params);
const startTime = Date.now();
try {
const result = await originalGetList(params);
console.log("请求成功,耗时:", Date.now() - startTime, "ms");
return result;
} catch (error) {
console.error("请求失败:", error);
throw error;
}
};
性能优化
1. 分页查询建议
// ✅ 推荐:合理的分页大小
const response = await client.models.users.filter({
pageSize: 20, // 10-50 条较合适
});
// ❌ 避免:单次查询过多数据
const response = await client.models.users.filter({
pageSize: 1000, // 不推荐,影响性能
});
2. 避免 N+1 查询
// ❌ 不推荐:循环调用 getOne
for (const id of userIds) {
const user = await client.models.users.getOne(id);
// 处理 user
}
// ✅ 推荐:使用 getList 批量查询
const users = await client.models.users.filter({
id_in: userIds, // 假设支持 IN 查询
});
3. 实现缓存
class CachedApiClient {
private cache = new Map<string, { data: any; timestamp: number }>();
private cacheTTL = 60000; // 1 分钟
async getListCached(params: any) {
const cacheKey = JSON.stringify(params);
const cached = this.cache.get(cacheKey);
if (cached && Date.now() - cached.timestamp < this.cacheTTL) {
return cached.data;
}
const data = await client.models.users.filter(params);
this.cache.set(cacheKey, { data, timestamp: Date.now() });
return data;
}
}
4. 并发控制
// 限制并发数
async function batchQuery(ids: string[], concurrency = 3) {
const results = [];
for (let i = 0; i < ids.length; i += concurrency) {
const batch = ids.slice(i, i + concurrency);
const batchResults = await Promise.all(
batch.map((id) => client.models.users.getOne(id))
);
results.push(...batchResults);
}
return results;
}
请求限制
频率限制
| 限制类型 | 限制值 |
|---|---|
| 每分钟 | 600 次请求 |
| 每小时 | 10,000 次请求 |
| 每天 | 100,000 次请求 |
数据量限制
| 限制类型 | 限制值 |
|---|---|
| 单次查询最多返回 | 100 条记录 |
| 响应体最大 | 10MB |
| 请求体最大 | 1MB |
并发限制
| 限制类型 | 限制值 |
|---|---|
| 每个应用最多并发连接 | 10 个 |
- 使用连接池管理请求
- 实现请求队列和限流机制
- 合理设置超时时间
原始 HTTP 请求(高级)
推荐使用 SDK,以下内容仅供需要底层实现的开发者参考。
签名生成
import crypto from "crypto";
function generateToken(
timestamp: number,
appCode: string,
datasetCode: string,
accessKey: string,
secretKey: string = "lovrabet"
): string {
const params: Record<string, string> = {
accessKey: accessKey,
timeStamp: timestamp.toString(),
appCode: appCode,
};
if (datasetCode) {
params.datasetCode = datasetCode;
}
// 按字典序排序参数
const sortedParams = Object.keys(params)
.sort()
.map((key) => `${key}=${params[key]}`)
.join("&");
// 计算 HMAC-SHA256
return crypto
.createHmac("sha256", secretKey)
.update(sortedParams, "utf8")
.digest("base64");
}
HTTP 请求示例
async function getListRaw() {
const timestamp = Date.now();
const appCode = "app-c2dd52a2";
const datasetCode = "0fefba76fe29440194841f4825df53ff";
const accessKey = "your-access-key";
const token = generateToken(timestamp, appCode, datasetCode, accessKey);
const response = await fetch(
"https://runtime.lovrabet.com/openapi/data/get-list",
{
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Time-Stamp": timestamp.toString(),
"X-App-Code": appCode,
"X-Dataset-Code": datasetCode,
"X-Token": token,
},
body: JSON.stringify({
appCode: appCode,
datasetCode: datasetCode,
paramMap: {
pageSize: 10,
currentPage: 1,
},
}),
}
);
return await response.json();
}
最佳实践
1. 错误处理和重试
async function apiCallWithRetry(
fn: () => Promise<any>,
maxRetries = 3,
delay = 1000
) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (error) {
if (error instanceof LovrabetError) {
// Token 过期可以重试
if (error.statusCode === 1003 && i < maxRetries - 1) {
await new Promise((resolve) => setTimeout(resolve, delay));
continue;
}
}
throw error;
}
}
}
// 使用
const users = await apiCallWithRetry(() => client.models.users.filter());
2. 日志记录
function logApiCall(
method: string,
params: any,
result: any,
duration: number
) {
console.log({
timestamp: new Date().toISOString(),
method: method,
params: params,
success: true,
duration: duration,
recordCount: result.tableData?.length || 0,
});
}
3. 监控和告警
class ApiMonitor {
private errorCount = 0;
private errorThreshold = 10;
async callWithMonitoring(fn: () => Promise<any>) {
try {
const result = await fn();
this.errorCount = 0; // 重置错误计数
return result;
} catch (error) {
this.errorCount++;
if (this.errorCount >= this.errorThreshold) {
// 触发告警
this.sendAlert("API 错误率过高");
}
throw error;
}
}
private sendAlert(message: string) {
// 发送告警通知
console.error("告警:", message);
}
}
相关文档
需要帮助?
如遇到问题:
- 查看本文档的错误码说明
- 查看 GitHub Issues
- 联系商务经理获取技术支持