An SDK for Dapr should provide serialization for two use cases. First, for API objects sent through request and response payloads. Second, for objects to be persisted. For both these use cases, a default serialization is provided. In the Java SDK, it is the DefaultObjectSerializer class, providing JSON serialization.
DaprClient client = (new DaprClientBuilder()).build();
client.invokeService("myappid", "saySomething", "My Message", HttpExtension.POST).block();
In the example above, the app will receive a POST
request for the saySomething
method with the request payload as "My Message"
- quoted since the serializer will serialize the input String to JSON.
POST /saySomething HTTP/1.1
Host: localhost
Content-Type: text/plain
Content-Length: 12
"My Message"
DaprClient client = (new DaprClientBuilder()).build();
client.saveState("MyStateStore", "MyKey", "My Message").block();
In this example, My Message
will be saved. It is not quoted because Dapr’s API will internally parse the JSON request object before saving it.
[
{
"key": "MyKey",
"value": "My Message"
}
]
DaprClient client = (new DaprClientBuilder()).build();
client.publishEvent("TopicName", "My Message").block();
The event is published and the content is serialized to byte[]
and sent to Dapr sidecar. The subscriber will receive it as a CloudEvent. Cloud event defines data
as String. Dapr SDK also provides a built-in deserializer for CloudEvent
object.
@PostMapping(path = "/TopicName")
public void handleMessage(@RequestBody(required = false) byte[] body) {
// Dapr's event is compliant to CloudEvent.
CloudEvent event = CloudEvent.deserialize(body);
}
In this case, the object is serialized to byte[]
as well and the input binding receives the raw byte[]
as-is and deserializes it to the expected object type.
DaprClient client = (new DaprClientBuilder()).build();
client.invokeBinding("sample", "My Message").block();
@PostMapping(path = "/sample")
public void handleInputBinding(@RequestBody(required = false) byte[] body) {
String message = (new DefaultObjectSerializer()).deserialize(body, String.class);
System.out.println(message);
}
It should print:
My Message
Object serialization and deserialization for invocation of Actor’s methods are same as for the service method invocation, the only difference is that the application does not need to deserialize the request or serialize the response since it is all done transparently by the SDK.
For Actor’s methods, the SDK only supports methods with zero or one parameter.
public static void main() {
ActorProxyBuilder builder = new ActorProxyBuilder("DemoActor");
String result = actor.invokeActorMethod("say", "My Message", String.class).block();
}
public String say(String something) {
System.out.println(something);
return "OK";
}
It should print:
My Message
Actors can also have state. In this case, the state manager will serialize and deserialize the objects using the state serializer and handle it transparently to the application.
public String actorMethod(String message) {
// Reads a state from key and deserializes it to String.
String previousMessage = super.getActorStateManager().get("lastmessage", String.class).block();
// Sets the new state for the key after serializing it.
super.getActorStateManager().set("lastmessage", message).block();
return previousMessage;
}
The default serializer for Dapr is a JSON serializer with the following expectations:
redis-cli MGET "ActorStateIT_StatefulActorService||StatefulActorTest||1581130928192||message
"This is a message to be saved and retrieved."
redis-cli MGET "ActorStateIT_StatefulActorService||StatefulActorTest||1581130928192||mydata
{"value":"My data value."}
byte[]
.byte[]
to object.byte[]
. When persisting, also encode as Base64 string. This is done natively by most JSON libraries.redis-cli MGET "ActorStateIT_StatefulActorService||StatefulActorTest||1581130928192||message
"VGhpcyBpcyBhIG1lc3NhZ2UgdG8gYmUgc2F2ZWQgYW5kIHJldHJpZXZlZC4="
redis-cli MGET "ActorStateIT_StatefulActorService||StatefulActorTest||1581130928192||mydata
"eyJ2YWx1ZSI6Ik15IGRhdGEgdmFsdWUuIn0="
As of now, the Java SDK is the only Dapr SDK that implements this specification. In the near future, other SDKs will also implement the same.