Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Give more information for custom Deserialization #2832

Open
brh opened this issue Oct 10, 2024 · 2 comments
Open

Give more information for custom Deserialization #2832

brh opened this issue Oct 10, 2024 · 2 comments
Labels

Comments

@brh
Copy link

brh commented Oct 10, 2024

What is your use-case and why do you need this feature?
This feature is needed to make migration easier. We are using Retrofit for now to make network calls and are looking to use kotlinx.serialization as it converter factory.
I am a part of a team where we have a large model set that was haphazardly migrated from Java.
So a small portion of the models look like this
NewsFeedItem <| ---- Post <| ------ Video
Post <| ------ Gallery
NewsFeedItem <| ---- Section <| ------ VideoSection
NewsFeedItem has just one property, Post has 22 properties, Video 6, Story 1.

NewsFeedItem is an abstract class, but Post is not.

So all of this is wrapped in a NewsFeed which has properties that are List<NewsFeedItem> and also List<Post>. That being said when you display this on screen it can be a list of Videos or a news stories, followed by a Video, which is then followed by a Section that is a group of Videos.

So far what we see is that when we deserialize (using Polymorphic without a lot of changes to our models) is that Video would be derialize and it's properties would be set, but the data that is defined in Post and NewsFeedItem it's superclass are not set they are all null.

We tried a custom KSerializer, but there seems to be no way to know what is in the Json being processed, decoder provides no key names and the order in the json coming from the server is not guaranteed.

Describe the solution you'd like
Pass the JsonElement (same one that is passed into JsonContentPolymorphicSerializer.selectDeserializer) as a parameter to KSerializer.deserialize then at least we can query the json (element.jsonObject["kind"]?.jsonPrimitive?.content) and set the superclass values as needed. As going to all our classes and making each subclass override all the properties of it's superclass is not practical for this project.

@brh brh added the feature label Oct 10, 2024
@brh
Copy link
Author

brh commented Oct 10, 2024

So for instance this in TreeJsonDecoder.kt:

@JsonFriendModuleApi
public fun <T> readJson(json: Json, element: JsonElement, deserializer: DeserializationStrategy<T>): T {
    val input = when (element) {
        is JsonObject -> JsonTreeDecoder(json, element)
        is JsonArray -> JsonTreeListDecoder(json, element)
        is JsonLiteral, JsonNull -> JsonPrimitiveDecoder(json, element as JsonPrimitive)
    }
    return input.decodeSerializableValue(deserializer)
}

Would change to this possibly:

@JsonFriendModuleApi
public fun <T> readJson(json: Json, element: JsonElement, deserializer: DeserializationStrategy<T>): T {
    val input = when (element) {
        is JsonObject -> JsonTreeDecoder(json, element)
        is JsonArray -> JsonTreeListDecoder(json, element)
        is JsonLiteral, JsonNull -> JsonPrimitiveDecoder(json, element as JsonPrimitive)
    }
    return input.decodeSerializableValue(deserializer, json)   <----------------- add param which needs to be pass to subsequent calls
}

@brh
Copy link
Author

brh commented Oct 10, 2024

After inspecting the code a little more seems this may not be possible, if not could JsonTransformingSerializer be augmented with a post object creation processor that also has the JsonElement as a parameter.

protected open fun transformDeserializedObject(object: T, element: JsonElement): JsonElement

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant