may i add a general comment? kotlinx serialization...
# serialization
m
may i add a general comment? kotlinx serialization is hard. anything but a direct conversion requires tremendous work. if it weren't for KMP i would stick with gson or moshi. Hope other json serialization libraries become KMP capable soon.
1
j
For me it is easier than gson and moshi 🤔
2
b
Hard to be MPP compat without reflection...
☝️ 2
☝🏼 1
j
can you share your problem?
b
Also I personally wouldn't say it's hard. Just different.
j
and gson looks dead, indeed I have an issue open since 2015 and I am receiving notifications about people hitting it nowadays
1
m
a whole bunch of problems which are mostly not easily covered by the docs, which are themselves quite complicated due to the complicated APIs. how many different ways are there to create a serializer? Which one do i need?
j
Precisely the docs are really good for me, I found everything I need without searching in Google.
m
1. so in my usecase i needed to serialize to different types depending on the content of an array. only after asking in this slack channel did i found out that i needed a JsonContentPolymorphicSerializer
👀 1
j
m
yes
j
probable a list of a sealed class is enough for your use case
m
2. this entire concept of the descriptor sounds good in theory but in practice creating them for types not easily covered in the docs is a complicated undertaking
I am using sealed classes
j
are you talking about custom serializers, no?
m
yes i am
3. i need to deserialize from an array to an object. creating the descriptor was majorly complicated since my array would be of type
Any
. the entire library though does not like the type
Any
b
Oh boy, that's some messy api design
😆 1
j
Without seeing the problem in code, I think that is the real problem, you shouldn't use Any
m
4. so my thought was to use buildClassSerialDescriptor but that only works on objects
as you might have guessed... the api is not under my control
j
but the API return a List<SomethingPolimorphysm>
why you need an Any?
b
Yeah, figured as much. :)
m
5. now i am relying buildSerialDescriptor which allows to provide the StructureKind.LIST but gives me warnings that it is discourraged to use
btw, the list looks something like
["create", true, {more: "properties"]
b
Which platforms are you targeting? You might not even need kotlinx.serialization
j
just create a sealed class:
Copy code
sealed class Something {
    data class one(...) : Something()
    data class two(...) : Something()
}
Copy code
data class data(val list: List<Something>)
m
@Big Chungus We hoping to target Android and iOS
The target object looks like:
class Operation(val type: String, val active: Boolean, properties: Map<String, Any>)
j
Copy code
sealed class Something {
    data class One(val myString: String) : Something()
    data class Two(val myBoolean: Boolean) : Something()
    data class Three(val more: Properties) : Something
}

data class Properties(val more: String)
m
@Javier My structure looks like this but the properties are a Map of anything
b
If it's just the two platforms, you might be better off just using native serialization libs for each platform with expect/actual bridge
j
that anything is really anything? or just another sealed class?
m
And that is where problem no 6. comes in. serialization is not able to handle the Any part. in the descriptor i tried using JsonElement but this actual wraps all values(incl primitives) in JsonElements which is not what i want.
b
You'll waste some rime on bridging, but will save tons by using libs you're comfortable with for such uncommon data structures
j
if it is a deterministic API, you should be cover it with sealed classes, if it isn't. well, time to ping backend devs
m
@Javier any structure that is serializable by json. Think of it like any "payload" that is not relevant for serialization but consumed further down in the app.
j
but if you are trying to create a custom serializer, probably it has a limit amount of posibilities, so covering them with sealed class should be enough, and having an Unknown branch, so if backend adds new posibiilities, they can be mapped to Unknown until you add the new classes
m
7. Same problem that
Any
can not be deserialied, it can also not be serialized as lengthily discoursed here: https://github.com/Kotlin/kotlinx.serialization/issues/746
@Javier with unknown you referee to "leave out"?
j
backend send, today, 5 posibilities, but they can send in the next month, 10 posibilities, you are only handing 5
so you can handle the 5 new posibilities as Unknown until you upgrade your app
I haven't see an
Any
which is not used with a generic (i.e:
<T : Any>
) that doesn't look like a smell
m
the combinations of properties that can be send is pretty vast and i don't even want to think about creating serializers for all the different types.
j
only when the library lacks of having enough power to type the things
and how the app will handle that Any without you indicating it?
b
Can you not just take that entire list as json string?
m
maybe what would be better is to not use the object serialization part of the library but parse everything to JsonObject and to recreate the model classes manually
j
because in that case, you should use a String, a JsonElement or something so
m
Well, possible, but the use case of Any is relevant as can be seen by all the comments and votes in the thread above
but ok... thanks for listening to me complaining. possibly this is not the library for me. going for Moshi or Gson would be more suitable at least on Android.
btw, the thread in the comment above this one asks for the same
Any
topic.
j
how do you solve this problem with Moshi?
m
moshi handles Any automatically
j
but how you handle that any later
what you will do with that
you will map it to something?
m
yes. i will extract the data i need "manually"
j
that is the point
what is the difference to indicate it directly with a sealed class instead of putting Any and mapping later?
m
in this case there are dozens of different types that can be created with such a create operation. it is not feasibly to create a serializer for each one seperatly.
j
but you are going to map it later
so you are going to create the code
m
yes. but as simple as property["text"} as String instead of 30 lines of a serializer
j
you don't need to create a serializer
m
and this is done close to the site where it is used not during the request serialization stage which is supposed to be generic
j
just data classes + sealed classes
m
This code already exists so i wants to consume the properties as a plain Map.
r
Not to derail this thread, but I have to agree with @Moritz Post. I really want to like kotlinx.serialization, but I still feel that I don't 'get' it despite reading the documentation hundreds of times. It's missing many simple and advanced capabilities compared to something like Jackson; I often find myself spending an inordinate amount of time trying to make things work, and there have been several instances where I've given up and used Jackson instead. A few examples off the top of my head: • Deserializing a response (
data class (a: A, b: B)
) where
b
needs to be a specific implementation based on the value of
a
. (Admittedly from a terrible vendor API) • Deserializing a flat top-level array as a class https://kotlinlang.slack.com/archives/C7A1U5PTM/p1629821041132400) • Writing hundreds of
@SerialNames
manually to convert snake_case to camelCase (https://github.com/Kotlin/kotlinx.serialization/issues/33) • Getting the raw JSON value of a key (I hope this doesn't come across as overly negative. I greatly appreciate the work that the team & community have put into it.)
c
If you're using Moshi, wouldn't you need a polymorphic deserializer there too?
t
I looked at kotlin serialization when I wanted to create a MPP (but so far mostly JVM and JS) client for an API returning hateoas resources. I think kotlin serialization is just too generic, as in if I want to make a web client for a json API it is much simpler to use “native” stuff like jackson (for jvm). if however you want to convert multiple serialization formats then kotlin serialization is quite good as you can more agnostic. I admit I got frustrated pretty quickly, so gave up after no more than few hours, but reading/writing to http is a solved problem, don’t really want to invest so much there
m
@Richard Gomez @thanksforallthefish Sorry for chiming in a little late. I agree with your assumption. I often times see comments from people wher it "just doesn't click" how custom serialization works. It is possibly an issue of the documentation in regards to the real complexity of the libraries APIs. Reading the docs does not make you understand the api of the library. You can not easily transfer the docs examples to your real world problem. And as we have seen in numerous comments here: not all questions have an easy answer.
But then again. I am glad that such a library exists and don't want to downplay the peoples hard work.
👍 1
t
absolutely, work is terrific. mine was more a consideration in the usual engineer direction: there is no silver bullet. because of what it tries to do, I think kotlin serialization might be too complicated in some scenario, where there are also established libraries that makes the effort of learning kotlin serialization a bit of a chore
👍 2