How to correctly serialize an mongoDB ObjectId with kotlinx

1k Views Asked by At

I am trying to serialize a MongoDB ObjectId using a Kotlin, Spring Boot, KMongo and Kotlinx. The problem is, that the ObjectId is getting serialized as timestamp: Expected Result:

{"name":"Game 1","url":"game1.url","id":"62332fc4112cd3545bc129ef"}

Actual Result:

{
  "name" : "Game 1",
  "url" : "game1.url",
  "id" : {
    "id" : {
      "timestamp" : 1647521732,
      "date" : "2022-03-17T12:55:32.000+00:00"
    }
  }
}

I tried many different approaches (e.g. this one recommended by KMongo) but they didn't work. Any suggestions where the error might be?


GamesController

@RestController
class GamesController(private val gamesService: GamesService) {

    @PostMapping("/games")
    fun addGame(@RequestBody addGameRequest: AddGameRequest): Game {
        return = gamesService.addGame(addGameRequest)
    }
}

AddGameRequest

data class AddGameRequest(@JsonProperty("name") val name: String, @JsonProperty("url") val url: String)

GamesService

@Service
class GamesService(
    mongoDBClient: MongoDBClient,
    @Value("\${gamesservice.collectionname}") final val collectionName: String
) {
    var gamesCollection: MongoCollection<Game> = mongoDBClient.gamesBlogDB.getCollection<Game>(collectionName)

    fun addGame(addGameRequest: AddGameRequest): Game {
        val newGame = Game(addGameRequest.name, addGameRequest.url)
        val result = newGame.apply { gamesCollection.insertOne(newGame) }
        return result
    }
}

Game

@Serializable
data class Game(
    var name: String,
    var url: String,
    @SerialName("_id") @Serializable(with = ObjectIdAsStringSerializer::class) var id: Id<Game> = newId()
) : RepresentationModel<Game>()

ObjectIdAsStringSerializer

object ObjectIdAsStringSerializer : KSerializer<Id<Game>> {
    override val descriptor: SerialDescriptor
        get() = PrimitiveSerialDescriptor("Id<Game>", PrimitiveKind.STRING)

    @Suppress("UNCHECKED_CAST")
    override fun deserialize(decoder: Decoder): Id<Game> {
        return IdGenerator.defaultGenerator.create(decoder.decodeString()) as Id<Game>
    }

    override fun serialize(encoder: Encoder, value: Id<Game>) {
        encoder.encodeString(value.toString())
    }
}
0

There are 0 best solutions below