Skip to main content

Core Concepts

This document introduces the core classes and concepts of Lovrabet Java OpenSDK, helping you understand the SDK's working principles in depth.


1. SDK Client (LovrabetSDKClient)

LovrabetSDKClient is the core class of the SDK, encapsulating all OpenAPI interface calls.

1.1 Creating Client

public LovrabetSDKClient(String accessKey, String baseUrl);

Parameters:

ParameterTypeRequiredDescription
accessKeyStringYesAccess key generated in application backend
baseUrlStringYesAPI server address: https://runtime.lovrabet.com/openapi

Example:

String accessKey = "ak-OD8xWhMOsL5ChQ3Akhv4uYYiu1fPOFQGVF9BULIeov8";
String baseUrl = "https://runtime.lovrabet.com/openapi";

LovrabetSDKClient sdkClient = new LovrabetSDKClient(accessKey, baseUrl);

1.2 Client Features

Thread Safety

LovrabetSDKClient is thread-safe and can be shared in multi-threaded environments:

// Recommended: Create singleton for reuse
public class SdkClientManager {
private static volatile LovrabetSDKClient instance;

public static LovrabetSDKClient getInstance() {
if (instance == null) {
synchronized (SdkClientManager.class) {
if (instance == null) {
instance = new LovrabetSDKClient(
ConfigManager.getAccessKey(),
ConfigManager.getBaseUrl()
);
}
}
}
return instance;
}
}

// Use in application
LovrabetSDKClient client = SdkClientManager.getInstance();

Automatic Authentication

The SDK automatically handles signature authentication for all requests, you don't need to worry about the signature algorithm implementation:

// The SDK automatically handles:
// 1. Generate timestamp
// 2. Build signature string
// 3. Calculate HMAC-SHA256 signature
// 4. Add authentication headers to HTTP request

LovrabetResult<?> result = sdkClient.getList(request); // Automatic signing

2. Request Object (LovrabetRequest)

LovrabetRequest encapsulates parameters required for API calls.

2.1 Class Definition

public class LovrabetRequest {
private Long id; // Primary key ID
private String appCode; // Application code (required)
private String modelCode; // Dataset code
private Map<String, Object> paramMap; // Business parameters

// Getters and Setters
}

2.2 Field Description

FieldTypeRequiredUsage ScenarioDescription
appCodeStringYesAll interfacesApplication code, obtained from application backend
modelCodeStringPartialData operation interfacesDataset code, identifies the dataset to operate on
idLongPartialgetOne, updatePrimary key ID of data record
paramMapMapNoMultiple scenariosPagination parameters, query conditions, data fields, etc.

2.3 Usage Examples

Basic Request (appCode only)

Used for application-level interfaces like getting dataset list:

LovrabetRequest request = new LovrabetRequest();
request.setAppCode("app-c2dd52a2");

Dataset Operation Request

Used for dataset-level interfaces like querying data list:

LovrabetRequest request = new LovrabetRequest();
request.setAppCode("app-c2dd52a2");
request.setModelCode("b460abdbb0fb49e1865110d9dfbbc9b4");

// Add pagination parameters
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("pageSize", 10);
paramMap.put("currentPage", 1);
request.setParamMap(paramMap);

Single Record Operation Request

Used for querying and updating specific records:

LovrabetRequest request = new LovrabetRequest();
request.setAppCode("app-c2dd52a2");
request.setModelCode("32c036010c504757b80d438e3c0ec8b7");
request.setId(513L);

// Update operation also needs to set fields to modify
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("TEXT_1", "New text content");
request.setParamMap(paramMap);

2.4 paramMap Usage Guide

paramMap is a flexible parameter container supporting multiple purposes:

Purpose 1: Pagination Parameters

Map<String, Object> paramMap = new HashMap<>();
paramMap.put("currentPage", 1); // Current page number, starts from 1
paramMap.put("pageSize", 20); // Records per page

Purpose 2: Data Fields (Create/Update)

Map<String, Object> paramMap = new HashMap<>();
paramMap.put("TEXT_1", "Order Number-001"); // Text field
paramMap.put("NUMBER_3", 100); // Number field
paramMap.put("DATETIME_1", System.currentTimeMillis()); // Timestamp
paramMap.put("SELECT_4", "china-north"); // Select field

Purpose 3: Query Conditions (if API supports)

Map<String, Object> paramMap = new HashMap<>();
paramMap.put("status", "active"); // Filter by status
paramMap.put("category", "product"); // Filter by category

3. Response Object (LovrabetResult)

LovrabetResult<T> is the unified response object for all API interfaces.

3.1 Class Definition

public class LovrabetResult<T> {
private boolean success; // Whether execution succeeded
private String resultCode; // Result code
private String resultMsg; // Result message
private T data; // Return data
private LovrabetPage page; // Pagination info (partial interfaces)
private List<LovrabetField> fieldList; // Field list (partial interfaces)

// Getters and Setters
}

3.2 Field Description

FieldTypeDescription
successbooleanWhether request succeeded, true indicates success, false indicates failure
resultCodeStringResult code, "0000" for success, specific error code for failure
resultMsgStringResult message, contains error details when failed
dataTReturned business data, type varies by interface
pageLovrabetPagePagination info (only returned by paginated query interfaces)
fieldListListField list (returned by certain interfaces)

3.3 Standard Patterns for Handling Response

Pattern 1: Basic Check

LovrabetResult<?> result = sdkClient.someMethod(request);

if (result.isSuccess()) {
// Success: process business data
Object data = result.getData();
System.out.println("Operation successful: " + data);
} else {
// Failure: handle error info
System.err.println("Operation failed [" + result.getResultCode() + "]: " + result.getResultMsg());
}

Pattern 2: Type-Safe Handling

// Get single record
LovrabetResult<?> result = sdkClient.getOne(request);

if (result.isSuccess()) {
Map<String, Object> data = (Map<String, Object>) result.getData();

// Access specific fields
String text = (String) data.get("TEXT_1");
Integer number = (Integer) data.get("NUMBER_3");

System.out.println("Text field: " + text);
System.out.println("Number field: " + number);
}

Pattern 3: List Data Handling

// Get list data
LovrabetResult<?> result = sdkClient.getList(request);

if (result.isSuccess()) {
List<Map<String, Object>> dataList = (List<Map<String, Object>>) result.getData();

System.out.println("Data count: " + dataList.size());

// Iterate through data
for (Map<String, Object> record : dataList) {
System.out.println("Record: " + record);
}
}

Pattern 4: Error Handling with Retry

int maxRetries = 3;
int retryCount = 0;
LovrabetResult<?> result = null;

while (retryCount < maxRetries) {
result = sdkClient.getOne(request);

if (result.isSuccess()) {
// Success, break loop
break;
} else {
retryCount++;
System.err.println("Attempt " + retryCount + " failed: " + result.getResultMsg());

if (retryCount < maxRetries) {
try {
Thread.sleep(1000); // Wait 1 second before retry
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}

// Final processing
if (result != null && result.isSuccess()) {
System.out.println("Data: " + result.getData());
} else {
System.err.println("Failed after multiple retries");
}

4. Authentication Mechanism

The SDK uses HMAC-SHA256 signature algorithm for authentication, ensuring request security and integrity.

4.1 Signature Process (Automatic by SDK)

Although the SDK handles signing automatically, understanding the signature process helps with troubleshooting:

Step 1: Collect Signature Parameters

The SDK collects the following parameters (sorted alphabetically):

  • accessKey: Access key
  • timeStamp: Timestamp (milliseconds)
  • appCode: Application code
  • datasetCode: Dataset code

Step 2: Build Signature String

accessKey=ak-xxx&appCode=app-xxx&datasetCode=xxx&timeStamp=1234567890

Step 3: Calculate HMAC-SHA256 Signature

Use a fixed key to HMAC-SHA256 encrypt the signature string, then Base64 encode.

Step 4: Add to Request Headers

The SDK automatically adds the following info to HTTP request headers:

  • X-Time-Stamp: Timestamp
  • X-App-Code: Application code
  • X-Dataset-Code: Dataset code
  • X-Token: Generated signature

4.2 Security Best Practices

✅ Correct Approach

// 1. Use environment variables
String accessKey = System.getenv("LOVRABET_ACCESS_KEY");

// 2. Use configuration files
@Value("${lovrabet.accessKey}")
private String accessKey;

// 3. Use secret management service
String accessKey = secretManager.getSecret("lovrabet-access-key");

❌ Wrong Approach

// ❌ Don't hardcode in code
String accessKey = "ak-OD8xWhMOsL5ChQ3Akhv4uYYiu1fPOFQGVF9BULIeov8";

// ❌ Don't commit to code repository
// git add config.properties (contains accessKey)

// ❌ Don't print in logs
logger.info("AccessKey: " + accessKey); // Dangerous!

4.3 Common Authentication Issues

Issue 1: "Invalid Token"

Causes:

  • Incorrect AccessKey
  • System time differs from server time by more than 10 minutes

Solution:

// Check system time
System.out.println("Current timestamp: " + System.currentTimeMillis());

// Confirm AccessKey
System.out.println("AccessKey first 10 chars: " + accessKey.substring(0, 10));

Issue 2: "AccessKey does not exist or has expired"

Solution:

  1. Log in to Lovrabet Platform
  2. Check if AccessKey has been generated and not expired
  3. Confirm OpenAPI feature is enabled
  4. If needed, regenerate AccessKey

5. Complete Request-Response Flow

The diagram below shows a complete API call flow:

┌─────────────────┐
│ Create Request │
│ Set parameters │
└────────┬────────┘


┌─────────────────┐
│ SDK Auto-sign │ ← Auto add timestamp, calculate signature
└────────┬────────┘


┌─────────────────┐
│ Send HTTP Req │ ← With signature headers
└────────┬────────┘


┌─────────────────┐
│ Server Verify │
└────────┬────────┘


┌─────────────────┐
│ Process Logic │
└────────┬────────┘


┌─────────────────┐
│ Return Result │ ← Contains success, data, etc.
└────────┬────────┘


┌─────────────────┐
│ App Process │ ← if (result.isSuccess()) { ... }
└─────────────────┘

Example Code

// 1. Create Request
LovrabetRequest request = new LovrabetRequest();
request.setAppCode("app-c2dd52a2");
request.setModelCode("32c036010c504757b80d438e3c0ec8b7");
request.setId(513L);

// 2-4. SDK automatically handles signing, sending, verification

// 5. Server processes and returns Result
LovrabetResult<?> result = sdkClient.getOne(request);

// 6. App processes result
if (result.isSuccess()) {
Map<String, Object> data = (Map<String, Object>) result.getData();
System.out.println("Query successful: " + data);
} else {
System.err.println("Query failed: " + result.getResultMsg());
}

Next Steps

Now you understand the core concepts of the SDK, recommended learning path:

  1. 📖 Quick Start Complete your first CRUD program in 5 minutes

  2. 📚 Core Concepts ← Current location Deep dive into SDK architecture

  3. 📋 API Reference ← Recommended next Browse complete API documentation

  4. 💡 Examples Learn 5 real-world scenarios

  5. 🚀 Best Practices Master production optimization techniques

  6. FAQ Resolve common questions


Need help? Visit FAQ or contact service@lovrabet.com