I'm trying to convert a fork of a library from usi...
# serialization
v
I'm trying to convert a fork of a library from using Jackson to using Kotlinx.serialization. I've never used Jackson before. Can anyone help me understand what this is doing:
Copy code
objectMapper.readValue<Map<String, Any>>(it)
And how I might write it using Kotlinx.serialization instead? In the context, it's extracting a JWT claim from a Json Web Token. I don't know what the type of the 'Any' is, but I suspect it's just a String, or possibly a List of Strings.
a
is
it
a string? My guess is that the KxS equivalent is decoding to
JsonObject
https://github.com/Kotlin/kotlinx.serialization/blob/v1.4.1/docs/json.md#json-elements you can try
Copy code
val jwtObj: JsonObject = Json.decodeFromString(it)
And then you can treat
JsonObject
like a key-value Map
v
Yes,
it
is a String. I'll try that, thanks.
Next problem is:
Copy code
response.body?.let { // type of it is T & Any, whatever that means!
  objectMapper.writeValueAsString(it)
}
I guess that Jackson is using reflection so can find out what the concrete class of
T
is, but kotlinx is not and I need to pass a SerializationStrategy - and since it's
T
, I don't know what type that is.
a
I’d need a bit more context to figure that one out
I think
T & Any
means definitely not null
v
The entire function call is:
Copy code
open fun <T> createResponse(contentType: MediaType, response: ResponseEntity<T>): APIGatewayProxyResponseEvent =
        when (response.body != null && serializationHandlerChain.supports(contentType, response.body)) {
            true -> contentType
            false -> MediaType.parse(router.defaultContentType)
        }.let { finalContentType ->
            APIGatewayProxyResponseEvent()
                .withStatusCode(response.statusCode)
                .withHeaders(response.headers.toMutableMap().apply { put("Content-Type", finalContentType.toString()) })
                .withBody(
                    response.body?.let {
//                        Json.encodeToString(it)
                        serializationHandlerChain.serialize(finalContentType, it as Any)
                    }
                )
        }
The call to
serializationHandlerChain.serialize(finalContentType, it as Any)
ultimately just ends with
objectMapper.writeValueAsString(body)
I can't just write
Json.encodeToString(it as Any)
a
this is Spring Boot?
v
No, not at all. It's https://github.com/moia-oss/lambda-kotlin-request-router - for AWS Lambda functions written in Kotlin. It's just a router.
I had some issues with the library as it stands, so I'm experimenting with a fork for my own wee project.
I have also experimented with writing my own router, but I'm not that clever.
a
the first thought that comes to mind is to make the function inline, and T reified
Copy code
inline fun <reified T> createResponse()
but I don’t think that will work because it’s
open
, and it’s probably too large/complicated to inline
I think probably the best is to add the Serializer into the
data class ResponseEntity
maybe
Copy code
data class ResponseEntity<T>(
    val statusCode: Int,
    val body: T? = null,
    val headers: Map<String, String> = emptyMap(),
    val serializer: KSerializer<T>,
)
if you made the helper functions
inline
and
reified T
then I think you could get the
KSerializer<T>
from the `SerializerModule`… maybe
v
A lot of changes required I fear.
All because I've got some
LocalDate
values to deal with 😞.
v
Yeah, I've done it myself. Just a lot of changes to even get the tests to compile just now.
a
yeah