Table of contents
Part of nurago, a collection of independent Go packages for backend services.
import "github.com/tecnickcom/nurago/pkg/valkey"
Package valkey wraps the valkey-go client
(https://github.com/valkey-io/valkey-go) for Valkey (https://valkey.io), a
Redis-compatible in-memory data store. It covers key/value storage, typed data
serialization, and Pub/Sub messaging behind a single Client type.
How It Works
New creates a Client given a SrvOptions (aliased from
valkey-go’s ClientOption) and a variadic list of Option values:
- The server address is validated before any network connection is attempted
(skipped when a client is injected via
WithValkeyClient, since no connection is dialed). - A valkey-go client is constructed (or injected via
WithValkeyClientfor tests). When at least one channel is declared withWithChannels, a pre-built, pinned Pub/Sub subscription command starts a background subscription that feedsClient.ReceiveandClient.ReceiveDataone message per call. The subscription runs untilClient.Closeis called: canceling theNewcontext does not stop it. - Encode and decode functions (defaulting to
DefaultMessageEncodeFuncandDefaultMessageDecodeFunc) are stored on the client and used transparently by the typed data methods.
Operations
Client.Set,Client.Get, andClient.Delprovide raw key/value access with expiration.Client.SetDataandClient.GetDataencode and decode Go values with the configuredTEncodeFuncandTDecodeFunc.Client.SendandClient.Receivecarry raw strings;Client.SendDataandClient.ReceiveDataapply the same codec and return the channel name with the decoded value.WithMessageEncodeFuncandWithMessageDecodeFuncreplace the default JSON+base64 codec.Client.HealthChecksends a PING and returns a wrapped error on failure.- A missing key surfaces as
ErrKeyNotFound; other configuration and subscription states surface as the exported Err values, all matchable with errors.Is. WithValkeyClientinjects a customVKClientfor testing.Client.Closedrains pending calls before releasing the connection, and is required to stop the background subscription when channels are configured.
Usage
srvOpts := valkey.SrvOptions{InitAddress: []string{"localhost:6379"}}
client, err := valkey.New(
ctx,
srvOpts,
valkey.WithChannels("events", "notifications"),
)
if err != nil {
return err
}
defer client.Close()
// Store and retrieve a typed value:
type Payload struct{ Message string }
if err := client.SetData(ctx, "my-key", Payload{"hello"}, time.Hour); err != nil {
return err
}
var p Payload
if err := client.GetData(ctx, "my-key", &p); err != nil {
return err
}
// Publish and consume a typed message:
if err := client.SendData(ctx, "events", Payload{"fired"}); err != nil {
return err
}
var event Payload
channel, err := client.ReceiveData(ctx, &event)
To swap in an encrypted codec, supply custom functions at construction time:
client, err := valkey.New(ctx, srvOpts,
valkey.WithMessageEncodeFunc(myEncryptAndEncode),
valkey.WithMessageDecodeFunc(myDecryptAndDecode),
)
When To Use
- You run Valkey rather than Redis and want the same shape of API as redis.
- Structs should round-trip without hand-written encoding at each call site.
Example
ctrl := gomock.NewController(exampleReporter{})
defer ctrl.Finish()
ctx := context.TODO()
vkc := mock.NewClient(ctrl)
// The client speaks the Valkey wire protocol, so a TTL becomes an EX
// argument on the SET command.
vkc.EXPECT().Do(ctx, mock.Match("SET", "greeting", "hello", "EX", "60"))
vkc.EXPECT().Do(ctx, mock.Match("GET", "greeting")).
Return(mock.Result(mock.ValkeyString("hello")))
vkc.EXPECT().Close()
// Real code omits WithValkeyClient and lets New dial the server
// described by SrvOptions.
client, err := valkey.New(
ctx,
libvalkey.ClientOption{InitAddress: []string{"127.0.0.1:6379"}},
valkey.WithValkeyClient(vkc),
)
if err != nil {
fmt.Println(err)
return
}
defer client.Close()
err = client.Set(ctx, "greeting", "hello", time.Minute)
if err != nil {
fmt.Println(err)
return
}
value, err := client.Get(ctx, "greeting")
fmt.Println(value, err)
// Output:
// hello <nil>
Full source is in example_valkey_test.go. More runnable examples are on pkg.go.dev.
Dependencies
Importing this package pulls 2 external modules:
github.com/valkey-io/valkey-gogolang.org/x/sys