title: Serializing message with protobuf for akka actor which contains serializable data
body: <p>I have a persistent actor which can receive one type of command <code>Persist(event)</code> where event is a type of <code>trait Event</code> (there are numerous implementations of it). And on success, this reponds with <code>Persisted(event)</code> to the sender.</p>
  
  <p>The event itself is serializable since this is the data we store in persistence storage and the serialization is implemented with a custom serializer which internally uses classes generated from google protobuf <code>.proto</code> files. And this custom serializer is configured in <code>application.conf</code> and bound to the base trait <code>Event</code>. This is already working fine.</p>
  
  <p><strong>Note:</strong> The implementations of <code>Event</code> are <em>not</em> classes generated by protobuf. They are normal scala classes and they have a protobuf equivalent of them too, but that's mapped through the custom serializer that's bound to the base Event type. This was done by my predecessors for versioning (which probably isn't required because this can be handled with plain protobuf classes + custom serialization combi too, but that's a different matter) and I don't wish to change that atm.</p>
  
  <p>We're now trying to implement cluster sharding for this actor which also means that my commands (viz. <code>Persist</code> and <code>Persisted</code>) also need to be serializable since they may be forwarded to other nodes.</p>
  
  <p>This is the domain model :</p>
  
  <pre><code>sealed trait PersistenceCommand {
    def event: Event
  }
  
  final case class Persisted(event: Event) extends PersistenceCommand
  final case class Persist(event: Event) extends PersistenceCommand
  </code></pre>
  
  <p>Problem is, I do not see an elegent way to make it serializable. Following are the options I have considered</p>
  
  <p><strong>Approach 1.</strong> Define a new proto file for <code>Persist</code> and <code>Persisted</code>, but what do I use as the datatype for <code>event</code>? I didn't find a way to define something like this :</p>
  
  <pre><code>  message Persist {
     "com.example.Event" event = 1 // this doesn't work
     }
  </code></pre>
  
  <p>Such that I can use existing Scala trait <code>Event</code> as a data type. If this works, I guess (it's far fetched though) I could bind the generated code (After compiling this proto file) to akka's inbuilt serializer for google protobuf and it may work. The note above explains why I cannot use <code>oneof</code> construct in my proto file.</p>
  
  <p><strong>Approach 2.</strong> This is what I've implemented and it works (but I don't like it)</p>
  
  <p>Basically, I wrote a new serializer for the commands and delegated seraizalition and de-serialization of <code>event</code> part of the command to the existing serializer.</p>
  
  <pre><code>class PersistenceCommandSerializer extends SerializerWithStringManifest {
    val eventSerializer: ManifestAwareEventSerializer = new ManifestAwareEventSerializer()
  
    val PersistManifest   = Persist.getClass.getName
    val PersistedManifest = Persisted.getClass.getName
    val Separator         = "~"
  
    override def identifier: Int = 808653986
  
    override def manifest(o: AnyRef): String = o match {
      case Persist(event)   =&gt; s"$PersistManifest$Separator${eventSerializer.manifest(event)}"
      case Persisted(event) =&gt; s"$PersistedManifest$Separator${eventSerializer.manifest(event)}"
    }
  
    override def toBinary(o: AnyRef): Array[Byte] = o match {
      case command: PersistenceCommand =&gt; eventSerializer.toBinary(command.event)
    }
  
    override def fromBinary(bytes: Array[Byte], manifest: String): AnyRef = {
      val (commandManifest, dataManifest) = splitIntoCommandAndDataManifests(manifest)
      val event                           = eventSerializer.fromBinary(bytes, dataManifest).asInstanceOf[Event]
      commandManifest match {
        case PersistManifest =&gt;
          Persist(event)
        case PersistedManifest =&gt;
          Persisted(event)
      }
    }
  
    private def splitIntoCommandAndDataManifests(manifest: String) = {
      val commandAndDataManifests = manifest.split(Separator)
      (commandAndDataManifests(0), commandAndDataManifests(1))
    }
  }
  </code></pre>
  
  <p>Problem with this approach is the thing I'm doing in <code>def manifest</code> and in <code>def fromBinary</code>. I had to make sure that I have the command's manifest as well as the event's manifest while serializing and de-serializing. Hence, I had to use <code>~</code> as a separator - sort of, my custom serialization technique for the manifest information.</p>
  
  <p>Is there a better or perhaps, a right way, to implement this? </p>
  
  <p>For context: I'm using ScalaPB for generating scala classes from <code>.proto</code> files and classic akka actors.</p>
  
  <p>Any kind of guidance is hugely appreciated!</p>