Search code examples
scalalagom

How does lagom manage event versioning?


Lets say we modified an event to have a new field added. I understand that we can handle the serialization for event mapping changes in this documentation https://www.lagomframework.com/documentation/1.5.x/scala/Serialization.html but how does lagom know which version the event is? When declaring and defining case classes events, we do not specify the event version. So how does lagom serialization know which event version mapping to use?

In the image below, there is a field called fromVersion. How does lagom know the current version of events pulled from event store datastore?

enter image description here


Solution

  • So, to implement migration you add following code:

      private val itemAddedMigration = new JsonMigration(2) {
        override def transform(fromVersion: Int, json: JsObject): JsObject = {
          if (fromVersion < 2) {
            json + ("discount" -> JsNumber(0.0d))
          } else {
            json
          }
        }
      }
    
      override def migrations = Map[String, JsonMigration](
        classOf[ItemAdded].getName -> itemAddedMigration
      )
    }
    

    That means that all new events of type ItemAdded now will have version 2. All previous events will be treated as version 1. It is defined in the class PlayJsonSerializer Please see the following code:

      private def parseManifest(manifest: String) = {
        val i = manifest.lastIndexOf('#')
        val fromVersion = if (i == -1) 1 else manifest.substring(i + 1).toInt
        val manifestClassName = if (i == -1) manifest else manifest.substring(0, i)
        (fromVersion, manifestClassName)
      }
    

    Also, you can check it in the database. I use Cassandra, I if I will open my database, in eventsbytag1 collection I can find the field ser_manifest where described version. Where is simple class - it is version 1, where you have specified additional '#2', it means version 2 and so on.

    If you need more information about how it works, you can check method fromBinary in class PlayJsonSerializer.