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

Lawik

04/12/2019, 1:37 PM
How can I register multiple serializers when using a class with generic type, for example:
Copy code
Response<Foo>
Response<Bar>
r

ribesg

04/12/2019, 1:57 PM
You can’t have multiple serializers for one type. Do you have custom serializers? Your example requires 3 serializers: one for
Response
, one for
Foo
and one for
Bar
. If all 3 have the
@Serializable
annotation it should just work.
l

Lawik

04/12/2019, 2:05 PM
All 3 have the
@Serializable
annotation.
this is my current code
Copy code
private val client = HttpClient {
        install(JsonFeature) {
            serializer = KotlinxSerializer().apply {
                register(Response.serializer(FooDTO.serializer()))
                register(Response.serializer(PersonDTO.serializer()))
            }
        }
    }
Sadly, this causes `PersonDTO`'s serializer to apply for both
PersonDTO
and
FooDTO
.
This is my
Response
class
Copy code
@Serializable
data class Response<T>(val code: Int, val body: T?)
r

ribesg

04/12/2019, 2:15 PM
You should not need to register anything
If you have
@Serializable
on all 3 models it just works (In a JVM context)
l

Lawik

04/12/2019, 2:18 PM
I'm working on JS at the moment, this is what I get when I don't register anything:
Copy code
"Fatal exception in coroutines machinery for CancellableContinuation(DispatchedContinuation[WindowDispatcher@1, [object Object]]){[object Response]}@2. Please read KDoc to 'handleFatalException' method and report this incident to maintainers; caused by ReceivePipelineException: Fail to run receive pipeline: NoTransformationFoundException: No transformation found: class JsHttpResponse -> class Response"
r

ribesg

04/12/2019, 2:20 PM
Ok, then if you’re not on the JVM you need to set all mappers manually for each class as reflection doesn’t work
I use
setMapper(MyDataClass::class, MyDataClass.serializer())
But I think you can’t deserialize generics? I don’t use JS so I’m not sure. You can’t deserialize generics in native
l

Lawik

04/12/2019, 2:21 PM
That brings me back to my original question, how can one do this when your class has a type parameter, the last setMapper/register overwrites the previous one of the same class 😅
r

ribesg

04/12/2019, 2:21 PM
You can’t
😔 1
Why don’t you just return
Foo
?
l

Lawik

04/12/2019, 2:23 PM
I want to put http info in the response class, status code, headers, etc.
r

ribesg

04/12/2019, 2:24 PM
Ok, that’s why you want a generic. Are you sure you’re going to use all that?
I just return the model
l

Lawik

04/12/2019, 2:25 PM
I probably will at some point, I intend to add more data to the
Response
class, error message(s) for instance.
r

ribesg

04/12/2019, 2:27 PM
Ok, but why? Why would you have error messages in there?
l

Lawik

04/12/2019, 2:28 PM
Where would you put them?
r

ribesg

04/12/2019, 2:29 PM
You can have a
Feature
which catches non-2xx status codes and throws an exception
If you have a standard error message object, then you can deserialize the body as an
ErrorBody
or something in this
Feature
I’m not sure about an API returning error messages which should be displayed to the user though, feels weird
l

Lawik

04/12/2019, 3:09 PM
Thanks, I'll try it out later tonight, if not, on Monday.