Search code examples
jsonscalajson4s

Parsing JSON with LINQ-style queries in Scala


Suppose I need to parse a JSON (see below).

{
  success: true
  statusCode: 0
  statusMessage: "Ok"
  payload { ... } // some actual data
}

First, I am parsing the "status" fields to get an instance of case class Status (see below)

case class Status(success: Boolean, code: Int, message: String)

val json = parse(text) // text is a JSON above

val statusList = for {
    JObject(obj) <- json
    JField("success", JBool(success)) <- obj
    JField("code", JInt(code)) <- obj
    JField("message", JString(message)) <- obj
  } yield Status(success, code, message)

Does it make sense ?

The type of statusList is List[Status]. It contains a single Status item. If the parsing fails the statusList is empty. I don't like it since I want Option[Status] rather than List[Status]

I can easily convert List[Status] to Option[Status] with headOption but I would like to get Option[Status] directly.

Can I parse the JSON with json4s to get Option[Status] without getting List[Status] first ?


Solution

  • You can use the XPath-like functions, together with toOption:

    val statusOpt = for {
        JBool(success) <- (json / "success").toOption
        JInt(code) <- (json / "code").toOption
        JString(message) <- (json / "message").toOption
      } yield Status(success, code, message)