Skip to Content

Java Client SDK

Installing Java client SDK

<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.

SyncOxiaClient client = OxiaClientBuilder.create("localhost:6648") .namespace("my-namespace") .syncClient();

Commonly used OxiaClientBuilder options:

MethodDescriptionDefault
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

// 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:

OptionPurpose
IfRecordDoesNotExistAssert the key is not currently set.
IfVersionIdEquals(long)Conditional write based on the current version.
AsEphemeralRecordBind 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

GetResult res = client.get("my-key"); log.info("Got key: {} - value: {} - version: {}", res.getKey(), res.getValue(), res.getVersion());

Available GetOption values:

OptionPurpose
ComparisonEqual (default)Exact-key lookup.
ComparisonFloorHighest key ≤ requested key.
ComparisonCeilingLowest key ≥ requested key.
ComparisonLowerHighest key strictly < requested key.
ComparisonHigherLowest key strictly > requested key.
IncludeValue(boolean) / ExcludeValueInclude 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.

// 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.

// 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.

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.

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 .

Last updated on