Search code examples
scalaplay-json

Scala - convert String to Json using Play json


I need help to parse a json string into scala class using playJson

I wrote a formatter but I don't know how to handle the nested arrays.

Where Document Case class is

case class Document(content: String, score: Double, size: Int, path:String)

and formatter

implicit val similarHashFormatter: Format[SimilarHash] = (
  ((__ \ "hits" \ "hits" \\ "fields")(0) \ "content_hash")(0).format[String] and
  (__ \ "hits"  \ "hits" \\ "_score").format[Double] and
  ((__ \ "hits" \ "hits" \\  "fields")(0) \ "ast_size")(0).format[Int] and
  ((__ \ "hits" \ "hits" \\ "fields")(0) \ "path")(0).format[String]
) (SimilarHash.apply, unlift(SimilarHash.unapply))

This is my source json

{
  "hits": {
    "hits": [
      {
        "score": 1.5204661,
        "fields": {
          "size": [
            557645
          ],
          "path": [
            "/user/ubuntu/app
          ],
          "content": [
            "images"
          ]
        }
      },
      {        
        "score": 1.5199462,
        "fields": {
          "size": [
            556835
          ],
          "path": [
            "/user/ubuntu/app
          ],
          "content": [
            "documents"
          ]
        }
      }
    ]
  }
}

Any idea ?


Solution

  • I figured out the solution based on oblivion's comment but without creating multiple reads.

      implicit val docReader: Reads[Document] = (
            (__ \ "fields" \ "content")(0).read[String] and
            (__  \ "_score").read[Double] and
            ((__ \  "fields") \ "size")(0).read[Int] and
            ((__ \ "fields") \ "path")(0).read[String]
          ) (Document.apply _)
    
    
      implicit val docsReader: Reads[Documents] = (
          (__ \ "hits" \ "max_score").read[Double] and
          (__ \ "hits" \ "hits").read[Seq[Document]]
        ) (Documents.apply _)
    

    ... and finally

    val response = Json.parse(inputStream).asOpt[Documents]