Java Client SDK
Installing Java client SDK
Maven
<dependency>
<groupId>io.github.oxia-db</groupId>
<artifactId>oxia-client</artifactId>
<version>${VERSION}</version>
</dependency>Javadoc documentation is available at https://oxia-db.github.io/oxia-client-java/apidocs/latest
Sync and Async APIs
Oxia provides two API flavors in the client:
- Sync: Easier and convenient to use. Methods are blocking and return the result of the operation.
- Async: Returns futures to track completion of the operations. Allows having more operations outstanding and achieving higher throughput.
Client API
Initializing the client
To use the Oxia client, you need to create a client instance. Once created, a client instance will be valid until it’s explicitly closed, and it can be used from different threads.
Sync
SyncOxiaClient client = OxiaClientBuilder.create("localhost:6648")
.namespace("my-namespace")
.syncClient();Commonly used OxiaClientBuilder options:
| Method | Description | Default |
|---|---|---|
namespace(String) | Oxia namespace. | "default" |
requestTimeout(Duration) | Deadline for each unary RPC. | 30s |
sessionTimeout(Duration) | Session timeout for ephemeral records. | 15s |
batchLinger(Duration) | How long to wait before flushing a batched request. | 5ms |
maxRequestsPerBatch(int) | Maximum operations per batched request. | 1000 |
clientIdentifier(String) | Stable client identity attached to ephemeral records. | Random UUID |
authentication(Authentication) | OIDC / bearer-token auth. | null |
enableTls(boolean) | Enable TLS for the gRPC channel. | false |
openTelemetry(OpenTelemetry) | Wire the SDK into an existing OpenTelemetry meter. | null |
loadConfig(...) | Populate the builder from a properties file, file handle, or Properties instance. | — |
Full option reference: OxiaClientBuilder Javadocs .
Writing records
Sync
// Write a record to Oxia with the specified key and value, and with the expectation
// that the record does not already exist.
PutResult res = client.put("my-key", "my-value".getBytes(), Set.of(IfRecordDoesNotExist));
// Write a record with the expectation that it has not changed since the previous write.
// If there was any change, the operation will fail
client.put("my-key", "my-value-2".getBytes(),
Set.of(IfVersionIdEquals(res.version().versionId())));Available PutOption values:
| Option | Purpose |
|---|---|
IfRecordDoesNotExist | Assert the key is not currently set. |
IfVersionIdEquals(long) | Conditional write based on the current version. |
AsEphemeralRecord | Bind the record to the client session — see ephemerals. |
PartitionKey(String) | Route the write to a specific shard. |
SequenceKeysDeltas(List<Long>) | Server-assigned monotonic suffixes — see sequence keys. |
SecondaryIndex(String, String) | Attach a secondary index entry at write time. |
Full reference: PutOption Javadocs .
Reading records
Reading the value of a record
Sync
GetResult res = client.get("my-key");
log.info("Got key: {} - value: {} - version: {}",
res.getKey(), res.getValue(), res.getVersion());Available GetOption values:
| Option | Purpose |
|---|---|
ComparisonEqual (default) | Exact-key lookup. |
ComparisonFloor | Highest key ≤ requested key. |
ComparisonCeiling | Lowest key ≥ requested key. |
ComparisonLower | Highest key strictly < requested key. |
ComparisonHigher | Lowest key strictly > requested key. |
IncludeValue(boolean) / ExcludeValue | Include or skip the value payload. |
UseIndex(String) | Look up via a named secondary index. |
PartitionKey(String) | Route the read to a specific shard. |
// Range-style Get: find the closest key <= the lookup key.
GetResult res = client.get("/users/50", Set.of(ComparisonFloor));Full reference: GetOption Javadocs .
Deleting records
Delete a single record by key. Supports conditional deletes using version-based expectations.
Sync
// Unconditional delete
client.delete("my-key");
// Conditional delete: only succeed if the version matches
client.delete("my-key", Set.of(IfVersionIdEquals(version.versionId())));Available DeleteOption values: IfVersionIdEquals(long), PartitionKey(String). Full
reference: DeleteOption Javadocs .
Deleting a range of records
Delete all records whose keys fall within a specified range.
Sync
// Delete all keys in the range [minKeyInclusive, maxKeyExclusive)
client.deleteRange("/users/", "/users//");Listing keys
List the keys within a specified range, without fetching the associated values.
Sync
List<String> keys = client.list("/users/", "/users//");
keys.forEach(key -> log.info("Key: {}", key));Scanning records
Scan records in a key range, returning both keys and values.
Sync
List<GetResult> results = client.rangeScan("/users/", "/users//");
results.forEach(r -> log.info("Key: {} - Value: {} - Version: {}",
r.getKey(), new String(r.getValue()), r.getVersion()));ListOption and RangeScanOption accept PartitionKey(String), UseIndex(String), and
ShowInternalKeys(boolean).
Sessions and ephemerals
Sessions are created automatically the first time an ephemeral record is written. The client SDK handles heartbeats; records are cleaned up when the client closes or the session expires. See ephemerals for the lifecycle details.
Notifications and sequence updates
// Namespace change feed.
client.notifications(notification -> log.info("Got: {}", notification));
// Updates for a specific sequence prefix.
client.getSequenceUpdates("/events/", Set.of(PartitionKey("/events/")),
key -> log.info("New sequence key: {}", key));See notifications and sequence keys for semantics.
For the complete option reference across every operation see the Javadocs .