1

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?

pme
  • 14,156
  • 3
  • 52
  • 95
ps0604
  • 1,227
  • 23
  • 133
  • 330

1 Answers1

0

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.

pme
  • 14,156
  • 3
  • 52
  • 95
  • This works, but how to generate at runtime the `MyClass` case class and object? Also, I think you have a typo, do you mean `myClass` instead of `json` in the validate function? – ps0604 Nov 19 '18 at 21:11
  • Why would anyone want to "generate at runtime" when there is a safer solution at compile time? – cchantep Nov 22 '18 at 08:29
  • @ps0604 as cchantep already asked, there is no reason why you shouldn't create MyClass statically. Just add them in your code and you are ready to go. - and I fixed the typo, thanks – pme Nov 22 '18 at 08:55