Table of Contents

Key/Value Store

Key/Value Store allows client applications to create 'buckets' and use them as immediately consistent, persistent associative arrays.

Under the covers KV is a client side construct that allows you to store and retrieve values by a key using JetStream as the stream persistence engine. It's a simple, yet powerful way to store and retrieve data.

To be able to use KV you need to enable JetStream by running the server with -js flag e.g. nats-server -js.

Key/Value Store Quick Start

Download the latest nats-server for your platform and run it with JetStream enabled:

$ nats-server -js

Install NATS.Net and NATS.Client.Serializers.Json from Nuget.

Note

See also Serialization section for more information about different serialization options.

Before we can do anything, we need a Key/Value Store context:

// required to serialize ad-hoc types
var opts = new NatsOpts { SerializerRegistry = NatsJsonSerializerRegistry.Default };

await using var nats = new NatsConnection(opts);

var js = new NatsJSContext(nats);
var kv = new NatsKVContext(js);

Let's create our store first. In Key/Value Store, a bucket is simply a storage for key/value pairs:

var store = await kv.CreateStoreAsync("shop_orders");

Now that we have a KV bucket in our stream, let's see its status using the NATS command line client:

$ nats kv ls
╭───────────────────────────────────────────────────────────────────────────────╮
│                               Key-Value Buckets                               │
├─────────────┬─────────────┬─────────────────────┬──────┬────────┬─────────────┤
│ Bucket      │ Description │ Created             │ Size │ Values │ Last Update │
├─────────────┼─────────────┼─────────────────────┼──────┼────────┼─────────────┤
│ shop_orders │             │ 2023-10-12 15:29:40 │ 0 B  │ 0      │ never       │
╰─────────────┴─────────────┴─────────────────────┴──────┴────────┴─────────────╯

We can save values in a bucket by putting them using a key, which is order-1 in our case. We can also retrieve the saved value by its key:

await store.PutAsync("order-1", new ShopOrder(Id: 1));

var entry = await store.GetEntryAsync<ShopOrder>("order-1");

Console.WriteLine($"[GET] {entry.Value}");
public record ShopOrder(int Id);

We can also confirm that our value is persisted by using the NATS command line:

$ nats kv get shop_orders order-1
shop_orders > order-1 created @ 12 Oct 23 15:31 UTC

{"Id":1}

Key/Value Store Watchers

Key/Value Store supports watchers that allow you to be notified when a value is added, updated or deleted from a bucket. Let's see how we can use watchers to be notified when a value is added to our bucket:

await foreach (var entry in store.WatchAsync<ShopOrder>(cancellationToken: cancellationToken))
{
    Console.WriteLine($"[RCV] {entry}");
}