Scala case having 22 fields but having issue with play-json in scala 2.11.5

为君一笑 提交于 2019-11-27 19:21:17
phadej

You can split your Reads definition:

val fields1to10: Reads[(A,B,C,D,E,F,G,H,I,J)] = ???
val fields11to20 = ???
val fields21to30 = ???

implicit val hugeCaseClassReads: Reads[HugeCaseClass] = (
  fields1to10 and fields11to20 and fields21to30
) { a, b, c => createHugeCaseClassFromThreeTuples(a, b, c) }

The reason why "functional syntax" doesn't work for more than 22 fields is because there are intermediate classes defined only up to 22: FunctionalBuilder


Fully written out for small example it would look like:

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

// Let's pretend this is huge:
case class Huge(a: Int, b: String, c: Boolean, d: List[Int])

val fields1to2: Reads[(Int, String)] = (
  (__ \ "a").read[Int] and
  (__ \ "b").read[String]
).tupled

val fields3to4: Reads[(Boolean, List[Int])] = (
  (__ \ "c").read[Boolean] and
  (__ \ "d").read[List[Int]]
).tupled

implicit val hugeCaseClassReads: Reads[Huge] = (
  fields1to2 and fields3to4
) {
  case ((a, b), (c, d)) =>  
    Huge(a, b, c, d)
}

And the result of tryint to validate null:

scala> JsNull.validate[Huge]
res6: play.api.libs.json.JsResult[Huge] = JsError(
  List(
    (/b,List(ValidationError(error.path.missing,WrappedArray()))),
    (/d,List(ValidationError(error.path.missing,WrappedArray()))),
    (/c,List(ValidationError(error.path.missing,WrappedArray()))),
    (/a,List(ValidationError(error.path.missing,WrappedArray())))))

As you can see, all fields are tried.


Or you could extend play with even more CanBuildNN classes: https://github.com/playframework/playframework/blob/2.3.6/framework/src/play-functional/src/main/scala/play/api/libs/functional/Products.scala


Yet I'd advice you to group fields in the SomeResponse class, for example address related etc. And write Reads and Writes instances by hand, if the JSON structure is flat and cannot be changed.

To make the example above compile, I had to make the type explicit:

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

// Let's pretend this is huge:
case class Huge(a: Int, b: String, c: Boolean, d: List[Int])

object Huge {
  val fields1to2: Reads[(Int, String)] = (
    (__ \ "a").read[Int] and
    (__ \ "b").read[String]
  ).tupled

  val fields3to4: Reads[(Boolean, List[Int])] = (
    (__ \ "c").read[Boolean] and
    (__ \ "d").read[List[Int]]
  ).tupled

  val f: ((Int, String), (Boolean, List[Int])) => Huge = {
    case ((a, b), (c, d)) => Huge(a, b, c, d)
  }

  implicit val hugeCaseClassReads: Reads[Huge] = (
    fields1to2 and fields3to4
  ) { f }

}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!