Go Client SDK
Installing Go client SDK
go get github.com/oxia-db/oxia/oxiaGoDoc documenation is available at https://pkg.go.dev/github.com/oxia-db/oxia/oxia
Sync and Async APIs
Oxia provides two API flavors in the client:
- Sync: Easier and convenient to use
- Async: Returns channels to track completion of the operations. Allows to have more operations outstanding and achieve higher throughput
All the features are available in either API.
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 go-routines.
Sync
client, err := oxia.NewSyncClient("localhost:6648")When creating the client is possible to pass several options, such as:
client, err := oxia.NewSyncClient("localhost:6648",
oxia.WithNamespace("my-namespace"),
oxia.WithBatchLinger(10*time.Milliseconds)),
)Available client options include:
| Option | Description | Default |
|---|---|---|
WithNamespace(namespace string) | Set the Oxia namespace to use | "default" |
WithBatchLinger(duration time.Duration) | How long to wait before sending a batched request | 5ms |
WithMaxRequestsPerBatch(count int) | Maximum number of requests in a batch | 1000 |
WithRequestTimeout(duration time.Duration) | How long to wait for responses before cancelling | 30s |
WithSessionTimeout(duration time.Duration) | Session timeout for ephemeral records | 15s |
WithMeterProvider(provider metric.MeterProvider) | Custom OpenTelemetry meter provider | noop.NewMeterProvider() |
WithGlobalMeterProvider() | Use the global OpenTelemetry meter provider | - |
WithIdentity(identity string) | Set a custom client identity | Random UUID |
WithTLS(config *tls.Config) | Configure TLS for secure connections | nil |
WithAuthentication(auth auth.Authentication) | Configure authentication | nil |
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.
insertedKey1, res1, err := client.Put(context.Background(), "my-key", []byte("value-1"), oxia.ExpectedRecordNotExists())
// Write a record with the expectation that it has not changed since the previous write.
// If there was any change, the operation will fail
insertedKey2, res2, err := client.Put(context.Background(), "my-key", []byte("value-2"), oxia.ExpectedVersionId(res1.VersionId))Reading records
Reading the value of a record
Sync
key, value, version, err := client.Get(context.Background(), "/my-key")Available options for get operation:
| Option | Description | Default |
|---|---|---|
ComparisonEqual() | Sets the Get() operation to compare the stored key for equality | Yes |
ComparisonFloor() | Search for the record whose key is the highest key < = to the supplied key | |
ComparisonCeiling() | Search for the record whose key is the lowest key > = to the supplied key | |
ComparisonLower() | Search for the record whose key is strictly < to the supplied key | |
ComparisonHigher() | Search for the record whose key is strictly > to the supplied key | |
IncludeValue(include bool) | Whether to include the value in the response, or just the version id | true |
UseIndex(indexName string) | Specify a different secondary index to search for the key | |
PartitionKey(partitionKey string) | Overrides the partition routing with the specified partitionKey instead of the regular record key |
Deleting records
Delete a single record by key. Supports conditional deletes using ExpectedVersionId for optimistic
concurrency control.
Sync
// Unconditional delete
err := client.Delete(context.Background(), "/my-key")
// Conditional delete: only succeed if the version matches
err = client.Delete(context.Background(), "/my-key", oxia.ExpectedVersionId(version.VersionId))Available options for delete operation:
| Option | Description | Default |
|---|---|---|
ExpectedVersionId(versionId int64) | Only delete if the record’s current version matches the expected one | |
PartitionKey(partitionKey string) | Overrides the partition routing with the specified partitionKey instead of the regular record key |
Deleting a range of records
Delete all records whose keys fall within a specified range.
Sync
// Delete all keys in the range [minKeyInclusive, maxKeyExclusive)
err := client.DeleteRange(context.Background(), "/users/", "/users//")Available options for delete-range operation:
| Option | Description | Default |
|---|---|---|
PartitionKey(partitionKey string) | Overrides the partition routing with the specified partitionKey instead of the regular record key |
Listing keys
List the keys within a specified range, without fetching the associated values.
Sync
// List all keys in the range
keys, err := client.List(context.Background(), "/users/", "/users//")
for _, key := range keys {
fmt.Println(key)
}Available options for list operation:
| Option | Description | Default |
|---|---|---|
UseIndex(indexName string) | List keys from a secondary index instead of the primary key space | |
ShowInternalKeys(show bool) | Whether to include Oxia’s own internal keys in the results | false |
PartitionKey(partitionKey string) | Overrides the partition routing with the specified partitionKey instead of the regular record key |
Scanning records
Scan records in a key range, returning both keys and values. Results are streamed through a channel.
Sync
ch := client.RangeScan(context.Background(), "/users/", "/users//")
for result := range ch {
if result.Err != nil {
log.Fatal(result.Err)
}
fmt.Printf("key: %s, value: %s, version: %d\n",
result.Key, string(result.Value), result.Version.VersionId)
}Available options for range-scan operation:
| Option | Description | Default |
|---|---|---|
UseIndex(indexName string) | Scan records using a secondary index | |
ShowInternalKeys(show bool) | Whether to include Oxia’s own internal keys in the results | false |
PartitionKey(partitionKey string) | Overrides the partition routing with the specified partitionKey instead of the regular record key |