Serialization
The client serializes your values on write and deserializes them on read, so you store and retrieve .NET objects directly. This article shows you how that works, how the type parameter controls deserialization, how raw bytes are handled, and how to avoid type-mismatch errors.
You do not call a serializer yourself. PutAsync<T> encodes the value you pass, and GetAsync<T> decodes it back into the type you request.
Store an object
Pass any serializable object to PutAsync. The client encodes it for you.
await client.PutAsync("user:1", new User
{
Name = "Ali",
Age = 30
});
Values are serialized with MessagePack. The client uses a contractless resolver, so plain types work without any serialization attributes: public properties and fields are encoded automatically. You do not need to annotate your models with [MessagePackObject].
Retrieve an object
Specify the type you expect as the type parameter of GetAsync. The client deserializes the stored bytes into that type.
var result = await client.GetAsync<User>("user:1");
if (result.IsSuccess)
{
Console.WriteLine(result.Value.Name);
}
The type parameter drives deserialization: GetAsync<User> decodes the value as a User, and GetAsync<string> decodes it as a string. Request the same type you stored.
Reading a value as a type that does not match what you stored causes a deserialization error, not a silent conversion. If you store a Customer and read it with GetAsync<Order>, the read fails. Keep the stored type and the requested type in sync across every service that touches the key.
Store raw bytes
A value of type byte[] is a special case: the client stores it as-is instead of running it through MessagePack, and returns it unchanged when you read it back as byte[].
byte[] payload = File.ReadAllBytes("blob.bin");
await client.PutAsync("blob:1", payload);
var result = await client.GetAsync<byte[]>("blob:1");
byte[] roundTripped = result.Value;
Use this when you already have encoded bytes, such as data serialized elsewhere or a binary blob, and you want Zaris to treat the value as opaque. Read a raw value back as byte[]; requesting a different type tries to deserialize the bytes and can fail.
Deserialize bytes yourself
When you hold serialized bytes, for example from a lower-level API, decode them into a type with the client's Deserialize<T> method. It uses the same serializer as GetAsync.
T value = client.Deserialize<T>(payload);
Content type is descriptive only
You can tag a stored value with a content type through options:
var options = Put.WithEntity("customer")
.WithContentType("application/json");
await client.PutAsync("cust:1", customer, options);
The content type is metadata that describes the value's format for interoperability. It does not change how the client encodes the value: values are still serialized with MessagePack regardless of the tag. Read the content type back from an item's metadata; do not rely on it to select a serializer.
Best practices
- Use strongly typed models and read each key back with the type you stored.
- Keep a model's shape consistent across the services that share a store, so all of them deserialize the same bytes successfully.
- Version your models carefully; a breaking change to a type can stop existing stored values from deserializing.
- Store
byte[]when you want Zaris to treat the value as opaque bytes.
Serialization behaves identically whether the store runs in-process or across a remote cluster.