I'm writing a Spring Boot backend for a Kotlin multiplatform ktor client. In most cases this works pretty well but I have one issue with serializing and deserialization booleans. This is my endpoint on server-side:
@GetMapping("/api/v1/user/existsByUsername/{username}", produces = [MediaType.APPLICATION_JSON_VALUE])
@ResponseBody
fun userExistsByUsername(@PathVariable("username") username: String) : ResponseEntity<Boolean> {
val exists = userService.usernameExists(username)
return ResponseEntity.status(HttpStatus.OK).body(exists)
}
I am expecting to get a result from this endpoint like {true}
but the client receives the body true
- and can't deserialize it. Can I force the endpoind in a simple way to add the curly brackets? Or is there a way to tell ktor to deserialization basic types as non-JSON?
In Spring Boot, primitive types (like boolean or integer) are serialized directly as a pure value in the response body, without being wrapped in an object (so you get true
and false
).
Make a class in your kotlin code
data class BooleanResponse(val value: Boolean)
then, dear @padmalcom, you can write something like
@GetMapping("/api/v1/user/existsByUsername/{username}", produces = [MediaType.APPLICATION_JSON_VALUE])
@ResponseBody
fun userExistsByUsername(@PathVariable("username") username: String): ResponseEntity<BooleanResponse> {
val exists = userService.usernameExists(username)
return ResponseEntity.status(HttpStatus.OK).body(BooleanResponse(exists))
}
that uses your class.
So your JSON return (rest endpoint) will be:
{
"value": true
}
with curly braces.
Ktor side then:
@Serializable
data class BooleanResponse(val value: Boolean)
val response: BooleanResponse = client.get("http://backend/api/v1/user/existsByUsername/someusername")
println(response.value) // here you get something like "true"
Fast & ̶f̶u̶r̶i̶o̶u̶s̶ simple