Best Practices
This document provides best practice guidelines for development based on the Lovrabet platform.
Prerequisites
If you're not familiar with Lovrabet's tool ecosystem, we recommend reading Developer Tools Overview first.
Core Philosophy
AI handles standardized repetitive tasks, humans focus on creative value output
- AI's Strength - Fast generation, standardization, zero-error basic functionality
- Human's Strength - Creative thinking, industry insights, user empathy
- Perfect Collaboration - AI provides infrastructure, humans build unique value
Application Scenarios
1. Mini Program Ecosystem Extension
Build WeChat Mini Programs and Alipay Mini Programs based on enterprise data:
import { createClient } from "@lovrabet/sdk";
const client = createClient({
appCode: "your-enterprise-app",
token: wx.getStorageSync("userToken"),
});
const customerData = await client.models.customers.filter({
region: "East China",
level: "VIP",
});
2. Workflow Automation
Build complex approval processes and data processing pipelines:
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. Multi-System Integration Hub
Connect Lovrabet with existing enterprise systems (ERP, CRM, OA):
const dataHub = {
lovrabet: await lovrabetClient.models.products.filter(),
erp: await erpConnector.getInventory(),
crm: await crmConnector.getCustomers(),
synchronize: () => {
// Complex data synchronization and transformation logic
},
};
Client Management
Frontend: Singleton Pattern Reuse
// ✅ Recommended: Singleton pattern, global reuse
// src/api/client.ts
import { createClient } from "@lovrabet/sdk";
export const client = createClient({
appCode: "your-app-code",
});
// Use in components
import { client } from "@/api/client";
// ❌ Not recommended: Creating new instance every time
function MyComponent() {
const client = createClient({ appCode: "..." }); // Creates on every render
}
Backend: Spring Bean Singleton
// ✅ Recommended: Use @Bean singleton
@Configuration
public class LovrabetConfig {
@Bean
public LovrabetSDKClient lovrabetSDKClient() {
return new LovrabetSDKClient(accessKey, baseUrl);
}
}
Security
AccessKey Management
# ✅ Use environment variables
export LOVRABET_ACCESS_KEY="ak-your-access-key"
// ❌ Never hardcode AccessKey in frontend
const client = createClient({
accessKey: "ak-xxx", // Dangerous! Will be exposed in browser
});
// ✅ Use Cookie or Token in browser
const client = createClient({
appCode: "your-app-code",
// Automatically uses Cookie authentication
});
Sensitive Data Masking
// Frontend: Mask phone number
const maskPhone = (phone: string) => {
return phone.replace(/(\d{3})\d{4}(\d{4})/, "$1****$2");
};
// 138****8000
// Backend: Log masking
String maskedPhone = phone.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
log.info("Customer phone: {}", maskedPhone);
Performance Optimization
Pagination and Debouncing
// ✅ Use pagination
const { data } = await client.models.customers.filter({
currentPage: 1,
pageSize: 20,
});
// ✅ Search debouncing
import { debounce } from "lodash-es";
const handleSearch = debounce(async (keyword) => {
await client.models.customers.filter({ searchKeyword: keyword });
}, 300);
Code Splitting
// ✅ Route lazy loading
import { lazy } from "react";
const CustomerAnalysis = lazy(() => import("./pages/CustomerAnalysis"));
Backend Caching
// Use Caffeine cache
private final Cache<String, Object> cache = Caffeine.newBuilder()
.maximumSize(1000)
.expireAfterWrite(5, TimeUnit.MINUTES)
.build();
Error Handling
Frontend Unified Handling
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 call failed:", error);
message.error("Network error, please try again later");
}
Backend Retry Mechanism
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("Retry failed", e);
}
}
return null;
}
Logging Standards
Structured Logging
@Slf4j
public class DataService {
public void createData(Map<String, Object> data) {
long startTime = System.currentTimeMillis();
log.info("Start operation - operation={}, dataSize={}", "create", data.size());
LovrabetResult<String> result = sdkClient.create(request);
long duration = System.currentTimeMillis() - startTime;
if (result.isSuccess()) {
log.info("Operation succeeded - id={}, duration={}ms", result.getData(), duration);
} else {
log.error("Operation failed - code={}, duration={}ms", result.getResultCode(), duration);
}
}
}
Testing Strategy
Frontend Unit Testing
import { render, screen, waitFor } from "@testing-library/react";
test("should load customers", async () => {
render(<CustomerList />);
await waitFor(() => {
expect(screen.getByText("Zhang San")).toBeInTheDocument();
});
});
Backend Integration Testing
@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);
}
}
Deployment Recommendations
Frontend Deployment
lovrabet build
# Artifacts in dist/ directory, deploy to CDN
Nginx Configuration:
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";
}
}
Backend Docker Deployment
FROM openjdk:11-jre-slim
WORKDIR /app
COPY target/myapp.jar app.jar
ENV LOVRABET_ACCESS_KEY=""
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
Health Check
@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;
}
Summary
| Practice Area | Key Points |
|---|---|
| Client Management | Use singleton pattern for both frontend and backend |
| Security | Never hardcode AccessKey in frontend |
| Performance Optimization | Pagination, caching, code splitting |
| Error Handling | Unified handling + retry mechanism |
| Log Management | Structured logging, sensitive info masking |
| Testing Strategy | Unit testing + integration testing |
| Deployment | Health checks, containerization |
Related Documentation
- Developer Tools Overview - Learn about the five-tool suite system
- Integration Development Step-by-Step Guide - Complete process from scratch
- TypeScript SDK Guide - Frontend data operations details
- Java SDK Guide - Backend data operations details
- OpenAPI Interface Documentation - HTTP API call details