Search code examples
scalacirce

How to check against an empty JSON


I am using https://circe.github.io/circe/ and would like to figure out, if a property has an empty JSON object or not. For example:

val json: String = """
  {
    "id": "c730433b-082c-4984-9d66-855c243266f0",
    "name": "Foo",
    "counts": [1, 2, 3],
    "values": {
    }
  }
"""  

As you can see on the code above, the property values is an empty JSON structure.
How to validate, if a property is empty or not?


Solution

  • There are lots of ways you could do this. For example:

    import io.circe.jawn.parse
    
    def valuesIsEmpty(in: String): Option[Boolean] = for {
      parsed    <- parse(in).right.toOption
      parsedObj <- parsed.asObject
      values    <- parsedObj("values")
      valuesObj <- values.asObject
    } yield valuesObj.size == 0
    

    And then:

    scala> valuesIsEmpty(json)
    res0: Option[Boolean] = Some(true)
    

    Here None would indicate that the input is not valid JSON or isn't an object with a values member.

    In general you wouldn't perform validation at this level, though—you'd build it into your decoder. For example:

    import io.circe.Decoder, io.circe.generic.semiauto.deriveDecoder
    
    case class Entry(id: String, name: String, counts: List[Int], values: Map[String, String])
    
    implicit val decodeEntry: Decoder[Entry] = deriveDecoder[Entry].emap {
      case e if e.values.isEmpty => Left("empty values")
      case e => Right(e)
    }
    

    And then:

    scala> io.circe.jawn.decode[Entry](json)
    res0: Either[io.circe.Error,Entry] = Left(DecodingFailure(empty values, List()))