Skip to main content

Serialization

Restate sends data over the network for storing state, journaling actions, awakeables, etc. There are multiple ways to specify which (de)serializers should be used.

Serializers and deserializers are abstracted using the interface dev.restate.sdk.common.Serde. We suggest to use Jackson serialization for Java and Kotlin serialization for Kotlin.

Jackson serialization

If you want to use Jackson Databind to (de)serialize POJOs, add the dependency sdk-serde-jackson. For example, in Gradle:


implementation("dev.restate:sdk-serde-jackson:0.9.2")

And then use JacksonSerdes. For example, to create a Serde for the Person class, you can do:


JacksonSerdes.of(Person.class);

Alternatively, you can also supply the TypeReference of a generic type, for example:


JacksonSerdes.of(new TypeReference<List<Integer>>() { });

Kotlin serialization

When using Kotlin, the Kotlin serialization library is included by default. You can manually create a Serde using Kotlin serialization using:


KtSerdes.json<MyDataClass>()

CoreSerdes for primitive types

If you don't want to depend on Jackson databind, we provide some primitive types support using jackson-core in CoreSerdes. The following serializers are included:


CoreSerdes.VOID,
CoreSerdes.JSON_BYTE,
CoreSerdes.JSON_STRING,
CoreSerdes.JSON_BOOLEAN,
CoreSerdes.JSON_BYTE,
CoreSerdes.JSON_SHORT,
CoreSerdes.JSON_INT,
CoreSerdes.JSON_LONG,
CoreSerdes.JSON_FLOAT,
CoreSerdes.JSON_DOUBLE

For example, to specify the serializer for state of type Long:


StateKey<Long> STATE_KEY = StateKey.of("my-key", CoreSerdes.JSON_LONG);

Protobuf messages

If you want to use Protobuf messages, add the dependency sdk-serde-protobuf. For example, in Gradle:


implementation("dev.restate:sdk-serde-protobuf:0.9.2")

And then use ProtobufParser:


ProtobufSerdes.of(Duration.parser());

Custom serialization

You can implement custom (de)serializers by implementing the dev.restate.sdk.common.Serde interface:


class MyPersonSerde implements Serde<Person> {
@Override
public byte[] serialize(Person person) {
// convert value to a ByteArray
return person.toBytes();
}
@Override
public Person deserialize(byte[] bytes) {
// convert value to Person
return Person.fromBytes(bytes);
}
}

And then use it, for example, to create a state key for Person objects:


StateKey<Person> PERSON_STATE_KEY = StateKey.of("person", new MyPersonSerde());