Serialization in Lagom

Reading Time: 2 minutes

In my previous blogs on Lagom, we discussed Persistent Entity and Read-side and Write side in Lagom. In this blog, I’m going to discuss how serialization is handled in Lagom. But before that let’s understand what serialization is ?



Serialization is a process of converting an object into the stream of bytes so that you can store or transmit it in memory, database etc. Its main purpose is to save the state of the object so that it can be recreated whenever needed.



Serialization in Lagom

Lagom uses Akka serialization mechanisms to bind serializers for each of the message sent over the wire. Preferably we use JSON. We can easily add Play-JSON serialization that is much more familiar to developers.

Why Serialization?

  • Persisting events and exchanging messages between the nodes of the cluster requires serialization.
  • Request and response messages uses serialization.
  • Without serialization it is not possible to deserialize  old objects.

Serialization using Play-JSON

To enable JSON serialization you need to follow given steps:

  • define your Format for each class that needs serialization
implicit val format: Format[ProductAdded] = Json.format

It is the best practice to define the Format as an implicit in the classes companion object, so that it can be found by implicit resolution.

  •  implement JsonSerializerRegistry
object UserSerializerRegistry extends JsonSerializerRegistry {
  override def serializers: immutable.Seq[JsonSerializer[_]] = immutable.Seq(
    JsonSerializer[Product],
    JsonSerializer[AddProductCommand],
    JsonSerializer[GetProductCommand],
    JsonSerializer[ProductAdded],
    JsonSerializer[InventoryState]
  )
}
  •  provide the serializer registry by overriding the jsonSerializerRegistry component method in your Application Loader
abstract class LagomPersistentEntityApplication(context: LagomApplicationContext)
  extends LagomApplication(context)
    with CassandraPersistenceComponents
    with AhcWSComponents {
override lazy val jsonSerializerRegistry: JsonSerializerRegistry = UserSerializerRegistry
}

Compression

Sometimes, for large messages it can be beneficial to enable compression.  That is done by using the JsonSerializer.compressed[T] builder method instead of the JsonSerializer.apply[T]. Compression reduces the size of messages. By default, it compresses the messages that are more than 32Kb.

Defining Format

There are 2 ways for that:

  • Automated mapping

The Json.format[MyClass] macro will inspect a case class for what fields it contains and produce a Format that uses the field names and types of the class in the resulting JSON. As we don’t have to apply each and every step individually, it is automated mapping.

implicit val format: Format[AddProductCommand] = Json.format[AddProductCommand]
  • Manual Mapping

In manual mapping we can use JSON combinators. In JSON combinators we don’t have to write Reads and Writes for producing a Format rather we can just use some functions. Other than cominators we can use reads and writes also. JSON combinators are useful when there is symmetry in Reads and Writes.

Limitation of Serialization in Akka-typed

In Akka Typed, messages often include a replyTo:ActorRef[T]  field so the actor handling the message can send a message back. For handling the serialization of the ActorRef[T] it is compulsory to use the Akka Jackson Serializer. You will have to use Akka Jackson to serialize your commands.

You can check for the demo code here.

That’s all about Serialization in Lagom. I hope that was helpful!

References

Written by 

Muskan Gupta is a Software Consulatant at Knoldus Inc having an experience of 2 years. She is passionate about Scala development and she has sound knowledge of Scala, Akka, Akka-Streams, Alpakka and Akka Http. She has interest in exploring different technologies.