title: How to combine polymorphic and transforming serializers for nested JSON, using Kotlin serialization?
body: <p>This is a simplified example of the JSON I want to work with:</p>
  <pre class="lang-json prettyprint-override"><code>{
    &quot;useless_info&quot;: &quot;useless info&quot;,
    &quot;data&quot;: {
      &quot;useless_info2&quot;: &quot;useless info 2&quot;,
      &quot;children&quot;: [
        {
          &quot;kind&quot;: &quot;Car&quot;,
          &quot;data&quot;: {
            &quot;id&quot;: 1,
            &quot;transmission&quot;: &quot;manual&quot;
          }
        },
        {
          &quot;kind&quot;: &quot;Boat&quot;,
          &quot;data&quot;: {
            &quot;id&quot;: 2,
            &quot;isDocked&quot;: true
          }
        }
      ]
    }
  }
  </code></pre>
  <p><code>children</code> is an array of <code>vehicle</code> objects. <code>vehicle</code> can be <code>boat</code> or <code>car</code>.</p>
  <h1>My Problem</h1>
  <p>The information that I want is nested quite deep (the real JSON is <strong>much</strong> deeply nested). A <strong>hack</strong> solution is to model the JSON exactly by writing dozens of nested data classes that references each other. I <strong>do not</strong> want to do this.</p>
  <p>My problem is that while I know how to use <code>JsonTransformingSerializer</code> to unwrap arrays of a single type, and <code>JsonContentPolymorphicSerializer</code> to work with objects of various types, in this situation I believe I require <strong>both</strong>, but I can't get it to work.</p>
  <h1>What I Did</h1>
  <h1>Assuming a single type</h1>
  <p>I tried understanding how it would work if it was a single type.</p>
  <p>If the objects I wanted where all of the same type, it would be trivial to implement a <code>JsonTransformingSerializer</code> to cut <em>right into</em> the data I want. In this example, I will assume I only care about the ID, so I can just create a generic <code>Vehicle</code> model.</p>
  <pre class="lang-kotlin prettyprint-override"><code>@Serializable
  data class VehicleResponse(
      @Serializable(with = VehicleResponseSerializer::class)
      @SerialName(&quot;data&quot;)
      val vehicles: List&lt;Vehicle&gt;
  )
  
  @Serializable
  data class Vehicle(val id: Int)
  
  object VehicleResponseSerializer : JsonTransformingSerializer&lt;List&lt;Vehicle&gt;&gt;(ListSerializer(Vehicle.serializer())) {
  
      override fun transformDeserialize(element: JsonElement): JsonElement {
          val vehicles = mutableListOf&lt;JsonElement&gt;()
  
          // equals: [{&quot;kind&quot;:&quot;Car&quot;,&quot;data&quot;:{&quot;id&quot;:1,&quot;transmission&quot;:&quot;manual&quot;}},{&quot;kind&quot;:&quot;Boat&quot;,&quot;data&quot;:{&quot;id&quot;:2,&quot;isDocked&quot;:true}}]
          val vehicleArray = element.jsonObject[&quot;children&quot;]!!.jsonArray
  
          vehicleArray.forEach { vehicle -&gt;
  
              // equals: {&quot;id&quot;:1,&quot;transmission&quot;:&quot;manual&quot;}}
              val vehicleData = vehicle.jsonObject[&quot;data&quot;]!!
  
              vehicles.add(vehicleData)
          }
  
          return JsonArray(vehicles.toList())
      }
  }
  </code></pre>
  <p>The code works perfectly. Calling it out from main, printing the result gives me:</p>
  <pre><code>VehicleResponse(vehicles=[Vehicle(id=1), Vehicle(id=2)])
  </code></pre>
  <h1>But they are actually Polymorphic!</h1>
  <p>Assuming one type does not work. I need to work with <code>Car</code> and <code>Boat</code>, and call their respective functions and properties.</p>
  <p>I tried to model the structure like this:</p>
  <pre class="lang-kotlin prettyprint-override"><code>@Serializable
  data class VehicleResponse(
      @Serializable(with = VehicleResponseSerializer::class)
      @SerialName(&quot;data&quot;)
      val vehicles: List&lt;Vehicle&gt;
  )
  
  @Serializable
  abstract class Vehicle {
      abstract val id: Int
  }
  
  @Serializable
  data class Car(
      override val id: Int,
      val transmission: String,
  ) : Vehicle()
  
  @Serializable
  data class Boat(
      override val id: Int,
      val isDocked: Boolean,
  ) : Vehicle()
  </code></pre>
  <h1>What I Want</h1>
  <ul>
  <li><p>I want to receive a JSON from a server, and instantly be able to deserialize it into a list of <code>Vehicle</code> objects, like the one <code>VehicleResponse</code> has.</p>
  </li>
  <li><p>I want to navigate through a deeply nested JSON, and unwrap an array that contains various <code>Vehicle</code> objects. For this, I assume I need to use <code>JsonTransformingSerializer</code>.</p>
  </li>
  <li><p>I want to use polymorphic deserialization to convert each of <code>Vehicle</code> into its corresponding subtype.</p>
  </li>
  </ul>
  <h1>The actual ACTUAL problem</h1>
  <p>The thing that is <strong>truly</strong> throwing me in a loop is that a polymorphic serializer just does not seem to fit. It's called first before I get to parse the JSON. How am I supposed to decide which serializer to use?</p>
  <p>Here's a test implementation:</p>
  <pre class="lang-kotlin prettyprint-override"><code>object VehiclePolymorphicSerializer: JsonContentPolymorphicSerializer&lt;VehicleResponse&gt;(VehicleResponse::class) {
  
      override fun selectDeserializer(element: JsonElement): DeserializationStrategy&lt;out VehicleResponse&gt; {
          println(&quot;\nselectDeserializer()\n&quot; +
                  &quot;base element:\n&quot; +
                  &quot;$element\n&quot;)
  
          // this return is a temporary hack, I just want to see the base element by printing it to the console
          return VehicleResponse.serializer()
      }
  
  }
  </code></pre>
  <p>It prints:</p>
  <pre><code>selectDeserializer()
  base element:
  {&quot;useless_info&quot;:&quot;useless info&quot;,&quot;data&quot;:{&quot;useless_info2&quot;:&quot;useless info 2&quot;,&quot;children&quot;:[{&quot;kind&quot;:&quot;Car&quot;,&quot;data&quot;:{&quot;id&quot;:1,&quot;transmission&quot;:&quot;manual&quot;}},{&quot;kind&quot;:&quot;Boat&quot;,&quot;data&quot;:{&quot;id&quot;:2,&quot;isDocked&quot;:true}}]}}
  </code></pre>
  <p>That's the whole initial JSON! How am I supposed to decide which deserialization strategy to use, if both <code>Car</code> and <code>Boat</code> are in there? The <code>JsonTransformingSerializer</code> is called <em>after</em> the <code>JsonContentPolymorphicSerializer</code>.</p>
  <p>Really not sure how am I supposed to proceed here. Would <em>really</em> appreciate even a slight hint.</p>