Golden OpenAPI Library
Introduction
The Golden OpenAPI Library is a Java client library that simplifies integration with the Golden API. It provides type-safe access to all API endpoints with pre-built Java objects, eliminating the need to manually handle HTTP requests and JSON serialization.
Source Code: trazadera-golden-openapi on GitHub
Installation
Maven Dependency
Add the following dependency to your pom.xml:
<dependency>
<groupId>com.trazadera</groupId>
<artifactId>trazadera-golden-openapi</artifactId>
<version>16-SNAPSHOT</version>
</dependency>
Repository Configuration
The library is published to GitHub Packages. Add the repository to your pom.xml:
<repositories>
<repository>
<id>github</id>
<url>https://maven.pkg.github.com/trazadera-public/trazadera-golden-openapi</url>
</repository>
</repositories>
GitHub Authentication
Create or update ~/.m2/settings.xml with your GitHub credentials:
<settings>
<servers>
<server>
<id>github</id>
<username>YOUR_GITHUB_USERNAME</username>
<password>YOUR_GITHUB_TOKEN</password>
</server>
</servers>
</settings>
Note: Generate a GitHub token with read:packages scope at GitHub Settings > Developer settings > Personal access tokens.
Quick Start
Basic Setup
import com.trazadera.golden.restclient.invoker.ApiClient;
import com.trazadera.golden.restclient.api.GoldenApi;
import com.trazadera.golden.restclient.api.EntityApi;
public class GoldenClientExample {
public static void main(String[] args) {
// Create and configure API client
ApiClient client = new ApiClient();
client.setBasePath("https://golden.yourcompany.com");
client.setBearerToken("golden:YourAccessToken");
// Create API instances
GoldenApi goldenApi = new GoldenApi(client);
EntityApi entityApi = new EntityApi(client);
// List entities
var entities = entityApi.getEntities();
entities.forEach(e -> System.out.println(e.getId()));
}
}
Search Records
import com.trazadera.golden.restclient.model.SearchRequest;
import com.trazadera.golden.restclient.model.SearchResponse;
// Create search request
SearchRequest request = new SearchRequest()
.entity("customers")
.query("[email protected]")
.limit(10);
// Execute search
SearchResponse response = goldenApi.search(request);
// Process results
System.out.println("Found " + response.getTotal() + " records");
for (var record : response.getRecords()) {
System.out.println("ID: " + record.getId());
System.out.println("Score: " + record.getScore());
System.out.println("Data: " + record.getData());
}
Upsert Records
import com.trazadera.golden.restclient.model.UpsertRequest;
import com.trazadera.golden.restclient.model.UpsertResponse;
import java.util.List;
import java.util.Map;
// Prepare record data
Map<String, Object> customerData = Map.of(
"id", "crm-12345",
"email", "[email protected]",
"full_name", "Jane Doe",
"phone", "+1-555-0200",
"source", "CRM"
);
// Create upsert request
UpsertRequest request = new UpsertRequest()
.entity("customers")
.records(List.of(customerData));
// Execute upsert
UpsertResponse response = goldenApi.upsert(request);
System.out.println("Inserted: " + response.getInserted());
System.out.println("Updated: " + response.getUpdated());
API Classes
The library is organized into three main packages:
api Package - API Classes
Each API module has a dedicated class:
Class | Description |
|---|---|
| Golden Records operations (search, upsert, buckets) |
| Entity management |
| Table operations |
| Resource configuration |
| Authentication, users, tokens |
| Background task management |
| File upload/download |
| System configuration |
model Package - Data Objects
Request and response objects for all API operations:
// Request objects
SearchRequest, UpsertRequest, QueryRequest, ExportRequest
// Response objects
SearchResponse, UpsertResponse, EntityResponse, TableResponse
// Entity objects
Entity, Record, Bucket, Table, Resource, Task
invoker Package - HTTP Client
The ApiClient class handles all HTTP communication:
ApiClient client = new ApiClient();
client.setBasePath("https://golden.yourcompany.com");
client.setBearerToken("golden:YourAccessToken");
// Optional: Configure timeouts
client.setConnectTimeout(30000); // 30 seconds
client.setReadTimeout(60000); // 60 seconds
Common Operations
Working with Entities
EntityApi entityApi = new EntityApi(client);
// List all entities
List<Entity> entities = entityApi.getEntities();
// Get entity details
Entity entity = entityApi.getEntity("customers");
System.out.println("Status: " + entity.getStatus());
System.out.println("Records: " + entity.getRecords());
System.out.println("Buckets: " + entity.getBuckets());
// Get entity statistics
EntityStatistics stats = entityApi.getEntityStatistics("customers");
System.out.println("Total records: " + stats.getTotalRecords());
System.out.println("Duplicate buckets: " + stats.getDuplicateBuckets());
// Trigger reindex
entityApi.indexEntity("customers");
Working with Buckets
GoldenApi goldenApi = new GoldenApi(client);
// List buckets needing review
List<Bucket> buckets = goldenApi.getBuckets("customers", "REVIEW", 0, 100);
for (Bucket bucket : buckets) {
System.out.println("Bucket: " + bucket.getId());
System.out.println("Records: " + bucket.getRecordCount());
System.out.println("Classification: " + bucket.getClassification());
}
// Get bucket details with records
BucketDetail detail = goldenApi.getBucket("customers", "bucket-001");
for (var record : detail.getRecords()) {
System.out.println(" Record: " + record.getId());
}
// Merge duplicates
MergeRequest mergeRequest = new MergeRequest()
.entity("customers")
.bucketId("bucket-001");
goldenApi.mergeBucket(mergeRequest);
// Disconnect records (not duplicates)
DisconnectRequest disconnectRequest = new DisconnectRequest()
.entity("customers")
.bucketId("bucket-001")
.recordIds(List.of("rec-002", "rec-003"));
goldenApi.disconnectBucket(disconnectRequest);
Working with Tables
TableApi tableApi = new TableApi(client);
// List tables
List<Table> tables = tableApi.getTables();
// Query table with filter
QueryRequest queryRequest = new QueryRequest()
.filter("email LIKE '%@example.com'")
.limit(100)
.offset(0);
QueryResponse result = tableApi.queryTable("customers", queryRequest);
for (var record : result.getRecords()) {
System.out.println(record);
}
// Export table
ExportRequest exportRequest = new ExportRequest()
.format("CSV")
.filter("created_at > '2024-01-01'");
byte[] exportData = tableApi.exportTable("customers", exportRequest);
Files.write(Path.of("customers.csv"), exportData);
Managing Tasks
TaskApi taskApi = new TaskApi(client);
// List running tasks
List<TaskInstance> tasks = taskApi.getTaskInstances("RUNNING", 0, 50);
for (TaskInstance task : tasks) {
System.out.println("Task: " + task.getId());
System.out.println("Type: " + task.getType());
System.out.println("Progress: " + task.getProgress() + "%");
System.out.println("Status: " + task.getStatus());
}
// Monitor task until completion
String taskId = "task-001";
TaskInstance task;
do {
task = taskApi.getTaskInstance(taskId);
System.out.println("Progress: " + task.getProgress() + "%");
Thread.sleep(5000); // Wait 5 seconds
} while (task.getStatus().equals("RUNNING"));
System.out.println("Task completed with status: " + task.getStatus());
// Cancel a task
taskApi.cancelTask(taskId);
Error Handling
API Exceptions
The library throws ApiException for all API errors:
import com.trazadera.golden.restclient.invoker.ApiException;
try {
Entity entity = entityApi.getEntity("nonexistent");
} catch (ApiException e) {
System.err.println("HTTP Status: " + e.getCode());
System.err.println("Error Body: " + e.getResponseBody());
switch (e.getCode()) {
case 401:
System.err.println("Authentication failed - check your token");
break;
case 403:
System.err.println("Access denied - insufficient permissions");
break;
case 404:
System.err.println("Entity not found");
break;
default:
System.err.println("API error: " + e.getMessage());
}
}
Retry Logic
Implement retry logic for transient failures:
public <T> T withRetry(Supplier<T> operation, int maxRetries) {
int retries = 0;
while (true) {
try {
return operation.get();
} catch (ApiException e) {
if (e.getCode() >= 500 && retries < maxRetries) {
retries++;
int waitTime = (int) Math.pow(2, retries) * 1000;
System.out.println("Retry " + retries + " after " + waitTime + "ms");
Thread.sleep(waitTime);
} else {
throw e;
}
}
}
}
// Usage
Entity entity = withRetry(() -> entityApi.getEntity("customers"), 3);
Connection Timeout Handling
try {
SearchResponse response = goldenApi.search(request);
} catch (ApiException e) {
if (e.getCause() instanceof java.net.SocketTimeoutException) {
System.err.println("Request timed out - try increasing timeout");
} else if (e.getCause() instanceof java.net.ConnectException) {
System.err.println("Cannot connect to server - check URL and network");
} else {
throw e;
}
}
Configuration Options
Client Configuration
ApiClient client = new ApiClient();
// Required settings
client.setBasePath("https://golden.yourcompany.com");
client.setBearerToken("golden:YourAccessToken");
// Timeout settings (milliseconds)
client.setConnectTimeout(30000); // Connection timeout
client.setReadTimeout(120000); // Read timeout for long operations
// Debug mode (logs all requests/responses)
client.setDebugging(true);
// Custom headers
client.addDefaultHeader("X-Custom-Header", "value");
// SSL configuration (for self-signed certificates - not recommended for production)
client.setVerifyingSsl(false);
Environment-Based Configuration
public class GoldenClientFactory {
public static ApiClient create() {
ApiClient client = new ApiClient();
// Read from environment variables
String url = System.getenv("GOLDEN_URL");
String token = System.getenv("GOLDEN_TOKEN");
if (url == null || token == null) {
throw new IllegalStateException(
"GOLDEN_URL and GOLDEN_TOKEN environment variables required"
);
}
client.setBasePath(url);
client.setBearerToken(token);
// Configure timeouts from environment or defaults
int connectTimeout = Integer.parseInt(
System.getenv().getOrDefault("GOLDEN_CONNECT_TIMEOUT", "30000")
);
int readTimeout = Integer.parseInt(
System.getenv().getOrDefault("GOLDEN_READ_TIMEOUT", "120000")
);
client.setConnectTimeout(connectTimeout);
client.setReadTimeout(readTimeout);
return client;
}
}
// Usage
ApiClient client = GoldenClientFactory.create();
GoldenApi goldenApi = new GoldenApi(client);
Best Practices
Connection Management
// Reuse ApiClient instance - it maintains connection pool
public class GoldenService {
private final ApiClient client;
private final GoldenApi goldenApi;
private final EntityApi entityApi;
public GoldenService(String url, String token) {
this.client = new ApiClient();
client.setBasePath(url);
client.setBearerToken(token);
this.goldenApi = new GoldenApi(client);
this.entityApi = new EntityApi(client);
}
// Use the shared instances for all operations
public SearchResponse search(String entity, String query) throws ApiException {
return goldenApi.search(new SearchRequest()
.entity(entity)
.query(query)
.limit(100));
}
}
Batch Operations
// Use batch upsert for better performance
public void syncRecords(List<Map<String, Object>> records) throws ApiException {
int batchSize = 1000;
for (int i = 0; i < records.size(); i += batchSize) {
List<Map<String, Object>> batch = records.subList(
i,
Math.min(i + batchSize, records.size())
);
UpsertRequest request = new UpsertRequest()
.entity("customers")
.records(batch);
UpsertResponse response = goldenApi.upsert(request);
System.out.println("Batch " + (i/batchSize + 1) +
": inserted=" + response.getInserted() +
", updated=" + response.getUpdated());
}
}
Async Operations with CompletableFuture
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class AsyncGoldenClient {
private final GoldenApi goldenApi;
private final ExecutorService executor;
public AsyncGoldenClient(ApiClient client) {
this.goldenApi = new GoldenApi(client);
this.executor = Executors.newFixedThreadPool(10);
}
public CompletableFuture<SearchResponse> searchAsync(
String entity, String query) {
return CompletableFuture.supplyAsync(() -> {
try {
return goldenApi.search(new SearchRequest()
.entity(entity)
.query(query)
.limit(100));
} catch (ApiException e) {
throw new RuntimeException(e);
}
}, executor);
}
// Search multiple queries in parallel
public List<SearchResponse> searchMultiple(
String entity, List<String> queries) {
List<CompletableFuture<SearchResponse>> futures = queries.stream()
.map(q -> searchAsync(entity, q))
.toList();
return futures.stream()
.map(CompletableFuture::join)
.toList();
}
}
Complete Example
import com.trazadera.golden.restclient.invoker.ApiClient;
import com.trazadera.golden.restclient.invoker.ApiException;
import com.trazadera.golden.restclient.api.*;
import com.trazadera.golden.restclient.model.*;
import java.util.*;
public class GoldenIntegrationExample {
public static void main(String[] args) {
// Configure client
ApiClient client = new ApiClient();
client.setBasePath(System.getenv("GOLDEN_URL"));
client.setBearerToken(System.getenv("GOLDEN_TOKEN"));
client.setConnectTimeout(30000);
client.setReadTimeout(120000);
// Create API instances
SecurityApi securityApi = new SecurityApi(client);
EntityApi entityApi = new EntityApi(client);
GoldenApi goldenApi = new GoldenApi(client);
try {
// Verify authentication
WhoAmI whoami = securityApi.whoami();
System.out.println("Authenticated as: " + whoami.getName());
System.out.println("Role: " + whoami.getRole());
// List entities
System.out.println("
Available entities:");
List<Entity> entities = entityApi.getEntities();
for (Entity entity : entities) {
System.out.println(" - " + entity.getId() +
" (" + entity.getRecords() + " records)");
}
// Search for a customer
System.out.println("
Searching for customer...");
SearchRequest searchRequest = new SearchRequest()
.entity("customers")
.query("[email protected]")
.limit(5);
SearchResponse searchResponse = goldenApi.search(searchRequest);
System.out.println("Found " + searchResponse.getTotal() + " records");
for (var record : searchResponse.getRecords()) {
System.out.println(" ID: " + record.getId());
System.out.println(" Score: " + record.getScore());
System.out.println(" Data: " + record.getData());
System.out.println();
}
// Upsert a new record
System.out.println("Upserting new record...");
Map<String, Object> newCustomer = new HashMap<>();
newCustomer.put("id", "api-" + System.currentTimeMillis());
newCustomer.put("email", "[email protected]");
newCustomer.put("full_name", "API Test User");
newCustomer.put("source", "API");
UpsertRequest upsertRequest = new UpsertRequest()
.entity("customers")
.records(List.of(newCustomer));
UpsertResponse upsertResponse = goldenApi.upsert(upsertRequest);
System.out.println("Inserted: " + upsertResponse.getInserted());
System.out.println("Updated: " + upsertResponse.getUpdated());
} catch (ApiException e) {
System.err.println("API Error: " + e.getCode());
System.err.println("Message: " + e.getResponseBody());
System.exit(1);
}
}
}
Troubleshooting
Maven Cannot Download Dependency
Problem: Could not resolve dependencies
Solution: Ensure GitHub authentication is configured in ~/.m2/settings.xml with a valid token.
SSL Certificate Errors
Problem: PKIX path building failed
Solution:
Import the server certificate into your Java truststore
Or (not recommended for production):
client.setVerifyingSsl(false)
Connection Refused
Problem: Connection refused
Solution:
Verify the server URL is correct
Check network connectivity and firewall rules
Ensure HTTPS is used (not HTTP)
401 Unauthorized
Problem: All requests return 401
Solution:
Verify token includes
golden:prefixCheck token hasn't expired
Ensure
setBearerToken()is called before creating API instances
Additional Resources
GitHub Repository - Source code and examples
Sample Usage - Complete example
Golden API - API overview
Developer Guide - Integration guide