最佳实践
本文档提供基于 Lovrabet 平台进行开发的最佳实践指南。
前置阅读
如果您还不了解 Lovrabet 的工具体系,建议先阅读 开发者工具全景。
核心理念
AI 负责可标准化的重复劳动,人类专注于创造性的价值输出
- AI 的优势 - 快速生成、标准化、零错误率的基础功能
- 人类的优势 - 创造性思维、行业洞察、用户共情能力
- 完美协作 - AI 提供基础设施,人类构建独特价值
应用场景示例
1. 小程序生态扩展
基于企业数据构建微信小程序、支付宝小程序:
import { createClient } from "@lovrabet/sdk";
const client = createClient({
appCode: "your-enterprise-app",
token: wx.getStorageSync("userToken"),
});
const customerData = await client.models.customers.filter({
region: "华东",
level: "VIP",
});
2. 工作流自动化
构建复杂的审批流程、数据处理管道:
const approvalWorkflow = {
trigger: await client.models.orders.filter({ status: "pending" }),
conditions: [
{ field: "amount", operator: ">", value: 10000 },
{ field: "customer.level", operator: "=", value: "VIP" },
],
actions: ["sendNotification", "createApprovalTask", "updateOrderStatus"],
};
3. 多系统集成中台
连接 Lovrabet 与企业现有系统(ERP、CRM、OA):
const dataHub = {
lovrabet: await lovrabetClient.models.products.filter(),
erp: await erpConnector.getInventory(),
crm: await crmConnector.getCustomers(),
synchronize: () => {
// 复杂的数据同步和转换逻辑
},
};
客户端管理
前端:单例模式复用
// ✅ 推荐:单例模式,全局复用
// src/api/client.ts
import { createClient } from "@lovrabet/sdk";
export const client = createClient({
appCode: "your-app-code",
});
// 在组件中使用
import { client } from "@/api/client";
// ❌ 不推荐:每次都创建新实例
function MyComponent() {
const client = createClient({ appCode: "..." }); // 每次渲染都创建
}
后端:Spring Bean 单例
// ✅ 推荐:使用 @Bean 单例
@Configuration
public class LovrabetConfig {
@Bean
public LovrabetSDKClient lovrabetSDKClient() {
return new LovrabetSDKClient(accessKey, baseUrl);
}
}
安全性
AccessKey 管理
# ✅ 使用环境变量
export LOVRABET_ACCESS_KEY="ak-your-access-key"
// ❌ 前端永远不要硬编码 AccessKey
const client = createClient({
accessKey: "ak-xxx", // 危险!会暴露在浏览器中
});
// ✅ 浏览器中使用 Cookie 或 Token
const client = createClient({
appCode: "your-app-code",
// 自动使用 Cookie 认证
});
敏感数据脱敏
// 前端:脱敏手机号
const maskPhone = (phone: string) => {
return phone.replace(/(\d{3})\d{4}(\d{4})/, "$1****$2");
};
// 138****8000
// 后端:日志脱敏
String maskedPhone = phone.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
log.info("客户电话: {}", maskedPhone);
性能优化
分页与防抖
// ✅ 使用分页
const { data } = await client.models.customers.filter({
currentPage: 1,
pageSize: 20,
});
// ✅ 搜索防抖
import { debounce } from "lodash-es";
const handleSearch = debounce(async (keyword) => {
await client.models.customers.filter({ searchKeyword: keyword });
}, 300);
代码分割
// ✅ 路由懒加载
import { lazy } from "react";
const CustomerAnalysis = lazy(() => import("./pages/CustomerAnalysis"));
后端缓存
// 使用 Caffeine 缓存
private final Cache<String, Object> cache = Caffeine.newBuilder()
.maximumSize(1000)
.expireAfterWrite(5, TimeUnit.MINUTES)
.build();
错误处理
前端统一处理
try {
const result = await client.models.customers.filter(params);
if (result.success) {
setData(result.data);
} else {
message.error(result.message);
}
} catch (error) {
console.error("API 调用失败:", error);
message.error("网络错误,请稍后重试");
}
后端重试机制
public <T> LovrabetResult<T> executeWithRetry(
Supplier<LovrabetResult<T>> operation, int maxRetries) {
for (int attempt = 0; attempt <= maxRetries; attempt++) {
try {
LovrabetResult<T> result = operation.get();
if (result.isSuccess()) return result;
Thread.sleep((long) Math.pow(2, attempt) * 1000);
} catch (Exception e) {
if (attempt == maxRetries) throw new RuntimeException("重试失败", e);
}
}
return null;
}
日志规范
结构化日志
@Slf4j
public class DataService {
public void createData(Map<String, Object> data) {
long startTime = System.currentTimeMillis();
log.info("开始操作 - operation={}, dataSize={}", "create", data.size());
LovrabetResult<String> result = sdkClient.create(request);
long duration = System.currentTimeMillis() - startTime;
if (result.isSuccess()) {
log.info("操作成功 - id={}, duration={}ms", result.getData(), duration);
} else {
log.error("操作失败 - code={}, duration={}ms", result.getResultCode(), duration);
}
}
}
测试策略
前端单元测试
import { render, screen, waitFor } from "@testing-library/react";
test("should load customers", async () => {
render(<CustomerList />);
await waitFor(() => {
expect(screen.getByText("张三")).toBeInTheDocument();
});
});
后端集成测试
@SpringBootTest
public class DataServiceIntegrationTest {
@Autowired
private DataService dataService;
@Test
public void testGetCustomers() {
List<Map<String, Object>> customers = dataService.getCustomers(1, 10);
assertNotNull(customers);
assertTrue(customers.size() > 0);
}
}
部署建议
前端部署
lovrabet build
# 产物在 dist/ 目录,部署到 CDN
Nginx 配置:
server {
listen 80;
root /var/www/your-app/dist;
location / {
try_files $uri $uri/ /index.html;
}
location ~* \.(js|css|png|jpg|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
后端 Docker 部署
FROM openjdk:11-jre-slim
WORKDIR /app
COPY target/myapp.jar app.jar
ENV LOVRABET_ACCESS_KEY=""
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
健康检查
@GetMapping("/health/lovrabet")
public Map<String, Object> checkHealth() {
Map<String, Object> health = new HashMap<>();
try {
long start = System.currentTimeMillis();
LovrabetResult<?> result = sdkClient.getDatasetCodeList(request);
health.put("status", result.isSuccess() ? "UP" : "DOWN");
health.put("responseTime", (System.currentTimeMillis() - start) + "ms");
} catch (Exception e) {
health.put("status", "DOWN");
health.put("error", e.getMessage());
}
return health;
}
总结
| 实践领域 | 核心要点 |
|---|---|
| 客户端管理 | 前后端都使用单例模式 |
| 安全性 | 永远不要在前端硬编码 AccessKey |
| 性能优化 | 分页、缓存、代码分割 |
| 错误处理 | 统一处理 + 重试机制 |
| 日志管理 | 结构化日志、敏感信息脱敏 |
| 测试策略 | 单元测试 + 集成测试 |
| 部署 | 健康检查、容器化 |
相关文档
- 开发者工具全景 - 了解五件套工具体系
- 集成开发步骤指引 - 从零开始的完整流程
- TypeScript SDK 指南 - 前端数据操作详解
- Java SDK 指南 - 后端数据操作详解
- OpenAPI 接口文档 - HTTP 接口调用详解