Anand Anand - 3 months ago 18
JSON Question

Not able to use JSON Macro Inception to convert nested JSON structure to Scala case class object

I have a requirement where the incoming JSON object is complex and mostly nested
ex:

"users": {
"utype": "PERSON",
"language":"en_FR",
"credentials": [
{
"handle": "xyz@abc.com",
"password": "123456",
"handle_type": "EMAIL"
}
],
"person_details": {
"primary": "true",
"names": [
{
"name_type": "OFFICIAL",
"title": "MR",
"given": "abc",
"family": "zat",
"middle": "pqs",
"suffix":"anathan"
}
],
"addresses": [
{
"ad_type": "HOME",
"line1": "Residential 2211 North 1st Street",
"line2": "Bldg 17",
"city": "test",
"county": "Shefield",
"state" : "NY",
"country_code": "xx",
"postal_code": "95131"
}
]
}
}


For parsing this structure I use the below Case Classes

case class PersonUser (
user_type:String,
language_code:String,
credentials:List[Credential],
person_details:PersonDetails
)

case class Credential(handle:String, password:String,handle_type:String)

case class PersonDetails(
primary_user:Boolean,
names: List[Name],
addresses:List[Address]
)

case class Name(
name_type: String,
title: String,
given: String,
family: String,
middle: String,
suffix:String
)

case class Address(
address_type: String,
line1: String,
line2: String,
city: String,
county: String,
state : String,
country_code: String,
postal_code: String
)


The statement to convert the json to scala case class object is failing:

implicit val testReads = Json.reads[PersonUser]


The errors says:

[scala-play-rest-example] $ compile
[info] Compiling 4 Scala sources to C:\Personal\Scala\scala-play-rest-example-master\target\scala-2.11\classes...
[error] C:\Personal\Scala\scala-play-rest-example-master\app\controllers\user\UserController.scala:16: **No implicit Reads for List[controllers.user.Credential], controllers.user.PersonDetails available.**
[error] implicit val testReads = Json.reads[PersonUser]


Can someone please help me out to find out a way to represent complex json structure in Scala and convert it using Macro Inception or some other ways?

Answer

You need to create Reads for all of your case classes, not just the top-level. For instance:

case class Credential(handle:String, password:String,handle_type:String)

object Credential {

  implicit val reads = Json.reads[Credential]

}

Once you have those, Json.reads[PersonUser] will be able to work.

Comments