kotlinx.serialization icon indicating copy to clipboard operation
kotlinx.serialization copied to clipboard

Convert @SerialName into @SerialPath (or add @SerialPath annotation)

Open mdeverdelhan opened this issue 5 years ago • 5 comments
trafficstars

What is your use-case and why do you need this feature?

In a JSON file I have an array of records like this:

{
  "id": "0000000000000001",
  "pathInJson": "a_value_for_fieldName",
  "nestedObject": {
    "otherFieldInNestedObject": "a_value_for_otherField",
    "xxxx": 0
  },
  "otherNestedObject": {
    "firstArray": [
       [ "aaa", "bbb", "ccc" ]
    ]
  }
}

But my data objects are much more simple (data class MyModel(val id : String, val fieldName : String, val otherField : String, val myList : List<String>)). So I tried to use the @SerialName annotation to map sub-field names to my class properties (with composed names like in @SerialName("nestedObject.otherFieldInNestedObject")). But it threw kotlinx.serialization.MissingFieldException: Field 'nestedObject.otherFieldInNestedObject' is required, but it was missing. :/

Describe the solution you'd like

So it would be nice if we could parse JSON objects this way:

@Serializable
data class MyModel(
    val id : String,
    @SerialPath("pathInJson")
    val fieldName : String,
    @SerialPath("nestedObject.otherFieldInNestedObject")
    val otherField : String,
    @SerialPath("otherNestedObject.firstArray[0]")
    val myList : List<String>
)

( or something compliant with JsonPath. See: https://goessner.net/articles/JsonPath/ )

mdeverdelhan avatar Jan 03 '20 20:01 mdeverdelhan

I don't think that this feature is compatible with the design of the library. In particular the design of the library assumes the child object to be described. Instead it may be useful to support the use of (private member class) delegate objects that are used for serialization but can be private and not used outside of the class.

pdvrieze avatar Jan 07 '20 17:01 pdvrieze

[...] the design of the library assumes the child object to be described.

Maybe that feature should be changed. Because with complicated JSON structures it is pretty painful.

mdeverdelhan avatar Jan 10 '20 20:01 mdeverdelhan

We definitely will not rename @SerialName or alter its behaviour since it already has proper, clear and simple semantics. @SerialPath/@JsonPath, however, may be considered as json-specific annotation and supported later. Currently your task can be done via custom serializers.

sandwwraith avatar Jan 12 '20 17:01 sandwwraith

Any news? with complicated JSON structures it is pretty painful -- that's right

el-qq avatar Oct 23 '23 20:10 el-qq

@el-qq The "simplest" solution I would suggest is the serial delegate pattern. This means that your main type is serializable with a custom serializer that forwards to a private class that is there just for serialization that has the intended structure and is serializable itself. In such case you use normal kotlin constructor calls.

pdvrieze avatar Oct 24 '23 10:10 pdvrieze