简体   繁体   中英

Play json parse missing field as empty array

Using play-json 2.3 How do i parse this

{i: 0}

into this

case class A(i: Int, s: Seq[Int])

i would very much like to reuse Json.format macro

at the moment it gives me "missing path s"

UPD: i ended up writing a custom format and pimping it onto JsPath:

implicit class JsPathExtensions(path: JsPath) {
  //return mzero if the path is missing
  def lazyFormatNullableM[T: Monoid](f: => Format[T]): OFormat[T] = OFormat(path.lazyReadNullable(f).map(_.orZero), new OWrites[T] {
    override def writes(o: T) = path.lazyWriteNullable(f).writes(o.some)
  })
}

If the path is missing, I don't see any way to utilize the macro without changing the class. In which case, you can define Reads using json combinators and use the macro for Writes .

import play.api.libs.json._
import play.api.libs.functional.syntax._

implicit val reads: Reads[A] = (
    (__ \ "i").read[Int] and 
    (__ \ "s").read[Seq[Int]].orElse(Reads.pure(Nil))
)(A.apply _)

implicit val writes: Writes[A] = Json.writes[A]

The json macros only cover a very limited range of use cases, and it's inevitable that you'll run into a case where you must write your own Reads or Writes .

The easiest way to utilise the Json.format[A] macro would be to slightly alter your definition of A :

case class A(i: Int, s: Option[Seq[Int]])

The usage of an Option here is pretty clear and you can map over it and do lots of good things, but if you really want to treat s like it's an empty collection, you could enhance your case class a little more:

case class Foo(i: Int, s: Option[Seq[Int]]) {
  lazy val theSeq:Seq[Int] = s.getOrElse(Seq[Int]())
}

Now if you access theSeq , there is absolutely no difference between incoming JSON that omitted s and JSON that supplied an empty array for s .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM