jsonscalaplayframeworkplayframework-2.0playframework-json

scala play reads parse nested json


I'm using implicit val reads to map Json like:

{
   "id": 1
   "friends": [
    {
      "id": 1,
      "since": ...
    },
    {
      "id": 2,
      "since": ...
    },
    {
      "id": 3,
      "since": ...
    }
  ]
}

to a case class

case class Response(id: Long, friend_ids: Seq[Long])

I can only make it work with an intermediate class that reflects the JSON friends structure. But I never use it in my app. Is there a way to write a Reads[Response] object so that my Response class would map directly to the JSON given?


Solution

  • You only need simple Reads[Response] with explicit Reads.seq() for friend_ids such as

    val r: Reads[Response] = (
      (__ \ "id").read[Long] and
        (__ \ "friends").read[Seq[Long]](Reads.seq((__ \ "id").read[Long]))
      )(Response.apply _)
    

    and result will be:

    r.reads(json)
    
    scala> res2: play.api.libs.json.JsResult[Response] = JsSuccess(Response(1,List(1, 2, 3)),)