Search code examples
scalaoption-typespray-json

How can I convert inbound empty optional array fields to None with spray-json?


The site I'm working with returns empty arrays for optional fields that have no values.

i.e. given these definitions -

case class Sample(f1: Option[Seq[F1]], id: Option[Int])

implicit val formatF1 = jsonFormat4(F1)
implicit val formatSample = jsonFormat2(Sample)

I get this -

Sample(Some(List()),Some(123))

instead of -

Sample(None,Some(123))

Is there an easy way to return None if the inbound is empty? I'm only interested in the read side, I won't be writing json.


Solution

  • I never used this plugin, but base on what I've read. I think you want something like this one.

    
    import spray.json._
    import spray.json.DefaultJsonProtocol._
    
    // Example Class for F1.
    case class F1(value: String) extends AnyVal
    case class Sample(f1: Option[Seq[F1]], id: Option[Int])
    
    implicit val formatF1 = jsonFormat4(F1)
    
    implicit object SampleFormat extends JsonFormat[Sample] {
    
      // Custom Reads validation.
      def read(json: JsValue): Record = json match {
        case JsObject(v) =>
          try {
            Sample({
              val F1_JSON = v("f1").convertTo[Seq[F1]]
              if (F1_JSON.isEmpty) None else Some(F1_JSON)
            },
            v("id").convertTo[Option[Int]])
          } catch {
            case _ => deserializationError("Cannot De-serialize to Sample object.")
          }
    
        case _ => deserializationError("Not a Sample Object.")
      }
    }