Reputation: 5458
I am investigating the use of Kotlin Serialization in my latest project
The Json I have to contend with is as follows:-
{
"countryCodeMapping": {
"ssd": [
{
"name": "South Sudan",
"alpha2": "ss",
"alpha3": "ssd"
}
],
"nic": [
{
"name": "Nicaragua",
"alpha2": "ni",
"alpha3": "nic"
}
],
"fin": [
{
"name": "Finland",
"alpha2": "fi",
"alpha3": "fin"
}
],
"cck": [
{
"name": "Cocos (Keeling) Islands",
"alpha2": "cc",
"alpha3": "cck"
}
],
"tun": [
{
"name": "Tunisia",
"alpha2": "tn",
"alpha3": "tun"
}
],
"uga": [
{
"name": "Uganda",
"alpha2": "ug",
"alpha3": "uga"
}
],
....
"myDescriptions": {
"1": {
"groupId": 1,
"description": "cvbxcvbxcvbxbxb",
"myTypes": [
"cxcvbxb",
"xcvxcbxxx",
"cvbxcvbxcxvcb"
]
},
"2": {
"groupId": 2,
"description": "vxvbxbxbxbx",
"myTypes": [
"xcvb",
"xcvbxcvb"
]
},
"3": {
"groupId": 3,
"description": "xcvbxcvbxcvbxcvb",
"myTypes": [
"xcvbxcvbxcvbx"
]
},
"4": {
"groupId": 4,
"description": "xcvbxcbxcvbxcb",
"myTypes": [
"xcvbxcxcvb"
]
},
"5": {
"groupId": 5,
"description": "xcvbxcvbxcvbxcvbx",
"myTypes": [
"xcvbxcvbxc",
"xcvbxcvbxcvbxb"
]
},
"6": {
"groupId": 6,
"description": "dfgsdfgsdgsdfgsdgsg",
"myTypes": [
I must decode the entire Json string, however I started with the countryCodeMapping
section as follows:-
@Serializable
data class Meta(
@SerialName("countryCodeMapping")
val mapping: CountryCodeMapping
)
@Serializable
data class CountryCodeMapping(val ssd: List<Country>)
@Serializable
data class Country(
@SerialName("name")
val name: String,
@SerialName("alpha2")
val alpha2: String,
@SerialName("alpha3")
val alpha3: String
)
val countryMap: Meta = Json {
isLenient = true
ignoreUnknownKeys = true
allowStructuredMapKeys = true
}.decodeFromString<Meta>(metaJson)
This works, however I obviously only decode Sudan
countryMap = Meta(mapping=CountryCodeMapping(ssd=[Country(name=South Sudan, alpha2=ss, alpha3=ssd)]))
What data class models do I require to enable me to achieve my goal?
UPDATE
The changes I had to make (Based on answer comment) were
@Serializable
data class Meta(
@SerialName("countryCodeMapping")
val mapping: Map<String, List<Country>>
)
@Serializable
data class Country(
@SerialName("name")
val name: String? = null,
@SerialName("alpha2")
val alpha2: String? = null,
@SerialName("alpha3")
val alpha3: String? = null
)
Upvotes: 3
Views: 3258
Reputation: 37879
When you have JSON objects like { "someKey": ..., "otherKey": ... }
, you have mainly 2 options to represent them:
Map<String, ...>
You current approach uses option 1 (with CountryCodeMapping
class, and hardcoded ssd
property). This approach is best when the keys are fixed and well known.
Approach 2 is better when the keys are dynamic and all the values have the same type, which is your case here.
To implement approach 2, use what @broot suggested: a Map<String, List<Country>>
instead of the CountryCodeMapping
class:
@Serializable
data class Meta(
@SerialName("countryCodeMapping")
val mapping: Map<String, List<Country>>
)
@Serializable
data class Country(
@SerialName("name")
val name: String,
@SerialName("alpha2")
val alpha2: String,
@SerialName("alpha3")
val alpha3: String
)
Upvotes: 2
Reputation: 28470
You can just use a regular map here:
val mapping: Map<String, List<Country>>
Upvotes: 4