This question is based on the following example, which is an attempt to deserialize a case class Node[Bird] from JSON.
import play.api.libs.json._
import play.api.libs.functional.syntax._
object ValidationTest {
case class Node[T](_id: Int, thing: T)
case class Bird(name: String, color: String)
// ERROR -- No apply function found matching unapply parameters
implicit val birdNodeFormat = Json.format[Node[Bird]]
val birdNodesJson: JsValue = Json.arr(
Json.obj(
"_id" -> 0,
"thing" -> Json.obj(
"name" -> "Cardinal",
"color" -> "Red"
)
),
Json.obj(
"_id" -> 1,
"thing" -> Json.obj(
"name" -> "Bluejay",
"color" -> "Blue"
)
)
)
val birdNodesResult = birdNodesJson.validate[Seq[Node[Bird]]]
}
In the preceding example, Scala is unable to resolve the proper apply/unapply functions for Node[Bird] for the format macro.
// ERROR -- No apply function found matching unapply parameters
implicit val birdNodeFormat = Json.format[Node[Bird]]
However, there is no problem with using a non-generic case class such as BirdNode.
case class BirdNode(_id: Int, thing: Bird)
// WORKS
implicit val birdNodeFormat = Json.format[BirdNode]
...
// WORKS
val birdNodesResult = birdNodesJson.validate[Seq[BirdNode]]
What is the best way to serialize/deserialize something like a Node[Bird] to/from JSON in Play 2.2?
You might have to define the format for Node[T]
without using the macro, but this works:
implicit val birdFormat: Format[Bird] = Json.format[Bird]
implicit def nodeFormat[T : Format]: Format[Node[T]] =
((__ \ "_id").format[Int] ~
(__ \ "thing").format[T]
)(Node.apply, unlift(Node.unapply))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With