1
votes

I have a file that contains the following array of JSON objects:

[
    {
      "type": "home",
      "number": 1111
    },
    {
      "type": "office",
      "number": 2222
    },
    {
      "type": "mobile",
      "number": 3333
    }
  ]

In Play Framework 2.x I would define an implicit Reads converter to read the file and convert it to a Scala structure:

implicit val implicitRead : Reads[MyClass] = (
      (JsPath \ "type").read[String] and
      (JsPath \ "number").read[Int]
)  (MyClass.apply _)

the Scala case class defined as:

case class MyClass (myType: String, myNumber: Int)

and parsing the JSON with:

val json = // file record content    
json.validate[MyClass] match {
  case s: JsSuccess[MyClass] => {
    val myObject: MyClass = s.get
    // do something with myObject
  }
  case e: JsError => {
    // error handling flow
  }

Now, my problem is that I know the structure of the JSON file only at runtime, not at compilation time. Is it possible to build both the implicit Reads converter and the case class at runtime?

1
Maybe this can help to start.Luis Miguel Mejía Suárez

1 Answers

0
votes

Use case classes directly with play-json:

Change the case class to:

case class MyClass (`type`: String, number: Int)

Add the json-formatter to the companion object:

object MyClass {
  implicit val format = Json.format[MyClass]
}

The validate function looks now:

val myClass = // file record content    
json.validate[Seq[MyClass]] match {
  case JsSuccess(myClasses, _) => myClasses
  case e: JsError =>  // handle error case
}

That's all you need. If you are not happy with the parameter names, you can use a Wrapper case class.