Question: I have a data class which has a property whose type is another data class, like this:

```
@Serializable
data class Vehicle (
  val color: String,
  val miles: Int,
  val year: Int,
  val garage: Garage
)

@Serializable
data class Garage (
  val latitude: Float,
  val longitude: Float,
  val name: String
)

```

Upon serializing, it produces output like this:

```
{ 
  "color" : "black" , 
  "miles" : 35000 , 
  "year" : 2017 , 
  "garage" : { "latitude" : 43.478342 , "longitude" : -91.337000 , "name" : "Paul's Garage" }
}

```

However I would like `garage` to be a literal string of its JSON representation, not an actual JSON object. In other words, the desired output is:

```
{ 
  "color" : "black" , 
  "miles" : 35000 , 
  "year" : 2017 , 
  "garage" : "{ \"latitude\" : 43.478342 , \"longitude\" : -91.337000 , \"name\" : \"Paul's Garage\" }"
}

```

How can I accomplish this in Kotlin? Can it be done with just `kotlinx.serialization` or is Jackson/Gson absolutely necessary?

Note that this output is for a specific usage. I cannot overwrite the base serializer because I still need to serialize/deserialize from normal JSON (the first example). In other words, the best scenario would be to convert the first JSON sample to the second, not necessarily to have the data class produce the 2nd sample directly.

Thanks!

Answer: 
Create a custom `SerializationStrategy` for `Vehicle` as follows:

```
val vehicleStrategy = object : SerializationStrategy<Vehicle> {
    override val descriptor: SerialDescriptor
        get() = buildClassSerialDescriptor("Vehicle") {
            element<String>("color")
            element<Int>("miles")
            element<Int>("year")
            element<String>("garage")
        }

    override fun serialize(encoder: Encoder, value: Vehicle) {
        encoder.encodeStructure(descriptor) {
            encodeStringElement(descriptor, 0, value.color)
            encodeIntElement(descriptor, 1, value.miles)
            encodeIntElement(descriptor, 2, value.year)
            encodeStringElement(descriptor, 3, Json.encodeToString(value.garage))
        }
    }
}

```

Then pass it to `Json.encodeToString()`:

```
val string = Json.encodeToString(vehicleStrategy, vehicle)

```

Result:

```
{"color":"black","miles":35000,"year":2017,"garage":"{\"latitude\":43.47834,\"longitude\":-91.337,\"name\":\"Paul's Garage\"}"}

```

More info [here](https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/serializers.md#hand-written-composite-serializer)
Here is a solution with a custom serializer for `Garage` and an additional class for `Vehicle`.

`Garage` to `String` serializer:

```
object GarageToStringSerializer : KSerializer<Garage> {
    override val descriptor = PrimitiveSerialDescriptor("GarageToString", PrimitiveKind.STRING)
    override fun serialize(encoder: Encoder, value: Garage) = encoder.encodeString(Json.encodeToString(value))
    override fun deserialize(decoder: Decoder): Garage = Json.decodeFromString(decoder.decodeString())
}

```

Auxiliary class:

```
@Serializable
data class VehicleDto(
    val color: String,
    val miles: Int,
    val year: Int,
    @Serializable(GarageToStringSerializer::class)
    val garage: Garage
) {
    constructor(v: Vehicle) : this(v.color, v.miles, v.year, v.garage)
}

```

The demanded result can be received with:

```
Json.encodeToString(VehicleDto(vehicle))

```