Serializing kotlin sealed classes (algebraic datatypes) to JSON

Pavlo Kerestey - October 10, 2019

At my current project, I am trying to discover how to represent algebraic datatypes in Kotlin. The reason I'd like to use them is the ability to exhaustively specify all the cases of a thing that I care about.

So, across the internet, people suggest using sealed classes for this purpose. This structure allows the typechecker to tell me if I have forgotten to handle some case deep down in the code.

Eventually, I need to communicate with the outside world using JSON and it took some time to understand how to serialise a sealed class with objects in it. The problem is, that the inner objects represent both a type, and a constructor of that type, but they are not values that can be written in JSON.

Using ideas from a StackOverflow answer, I have come up with this trick to help Jackson do the right thing:

import com.fasterxml.jackson.annotation.JsonGetter

sealed class Fruit {
    object Orange : Fruit()
    object Apple : Fruit()
    object Apricot : Fruit()

    @JsonGetter(“Fruit”)
    fun serialize(): String? = this::class.simpleName
}

If we now want to serialise an Orange into JSON, jsonMapper.writeValueAsString(Fruit.Orange) will produce something like this:

{ “Fruit”: “Orange” }

The reason it works in my understanding, is that every object in Fruit inherits the serialize() function and the @JsonGetter too. So Fruit.Orange.serialize() will be "Orange"