https://kotlinlang.org logo
#ktor
Title
# ktor
s

savrov

08/03/2020, 9:58 PM
Copy code
@Serializable
class SomeRequestBody(
    @SerialName("name_field")
    val name: String?
)
In KTOR Server, I have defined EP with such a request body. The problem is, that it works, if json looks like:
Copy code
{
  "name": "some-name-string"
}
but does not work if im trying to do the same with
Copy code
{
  "name_field": "some-name-string"
}
Do you know how to fix it? P.S. Content negotiation is enabled in application module like
Copy code
install(ContentNegotiation) {
   gson {
      setPrettyPrinting()
   }
}
Thank you in advance
j

jorge.rego

08/04/2020, 7:32 AM
AFAIK, if you use content negotiation, you don’t need to use serializable. This means you can expect your json to have a “name” field, not a “name_field” field. Do you really need to have a body with “name_field”?
s

savrov

08/04/2020, 7:34 AM
Yeah, i have more complex names like
date_something
, but i dont want to use an underscore in source code.
j

jorge.rego

08/04/2020, 7:47 AM
yep, I understand. Not sure how content negotiation feature works behind the scenes, but gson will work in its way and you are using Serializable in your annotations. They are different content negotiation options. Can you try the following?
Copy code
install(ContentNegotiation) {
    serialization()
}
Also Gson includes a way to change the serialized name, but the annotation is not “@SerialName”, you need to use “@SerializedName” https://www.javadoc.io/doc/com.google.code.gson/gson/2.6.2/com/google/gson/annotations/SerializedName.html
Sorry, didn’t realise the annotation could be wrong. If you change it to the one I’ve written in my previous comment you should be able to use Gson as you did before in content negotiation
s

savrov

08/04/2020, 1:39 PM
Great, thank you very much! You gave me an idea (since i have models defined in mpp module) of what I’m doing wrong. first of all, i’ll switch from
gson
to
kotlinx.serialization
then i should to write a custom serializer for my ApiResponse<T>. It looks a bit tricky, but will give a try
Now I’m trying to serialize a generic class 
ApiResponse<T>
 with 
kotlinx.serialization
. So i’ve created a
ApiResponseSerializer
class, with help of docs. But now i don’t understand how to use that serializer, since none of provided methods doesn’t seem to suit to me. That is the place where i need a help. My ApiResponse<T> is defined like:
Copy code
data class ApiResponse<T>(
    val data: T? = null,
    val error: ApiError? = null
)
And the regular usage (in KTOR) is
Copy code
respond(
    HttpStatusCode.Created,
    ApiResponse(data = response.data)
)
I don’t know where i can “attach” my serializer to 
data
 field of my 
ApiResponse
 class. Thank you in advance.
j

jorge.rego

08/04/2020, 2:59 PM
What I would do here is to use Gson and annotate fields with this: https://www.javadoc.io/doc/com.google.code.gson/gson/2.6.2/com/google/gson/annotations/SerializedName.html This should work without writing any serializer (unless you need to serialize complex data). And when installing content negotiation, you can configure it in case you need it.
Copy code
install(ContentNegotiation) {
   gson {
      // HERE YOU ARE CONFIGURING YOUR SERIALIZER
      setPrettyPrinting()
   }
}
s

savrov

08/04/2020, 3:04 PM
but gson is not multiplatform, so i can not use it in my mpp module
so i need to use a kotlinx.serialization
j

jorge.rego

08/04/2020, 3:08 PM
ah ok, then I said nothing.
s

savrov

08/04/2020, 3:09 PM
but still u were helpfull, like a batman)
😄 2
👍 1
75 Views