Validating Json with Reads[T] in Play Framework

Looking at a simple Scala Play JSON example (from the Play docs) to validate JSON (type JsValue) against a case class:

import play.api.libs.json._
import play.api.libs.functional.syntax._
import play.api.data.validation.ValidationError

scala> implicit val creatureReads: Reads[Creature] = (
     |  (__ \ "name").read[String] and
     |  (__ \ "isDead").read[Boolean])
<console>:17: error: type mismatch;
 found   : play.api.libs.functional.FunctionalBuilder[play.api.libs.json.Reads]
#CanBuild2[String,Boolean]
 required: play.api.libs.json.Reads[Creature]
        (__ \ "name").read[String] and
                                   ^

Then, eventually call this:

scala> val creature = Json.obj(  "name" -> "zombie", "isDead" -> true )
creature: play.api.libs.json.JsObject = {"name":"zombie","isDead":true}

scala> creature.validate[Creature]
...

But, how can I resolve the type mismatch I'm seeing?

Answers


You're almost there—all you need to do is apply your CanBuild2 to the Creature constructor:

implicit val creatureReads: Reads[Creature] = (
  (__ \ "name").read[String] and (__ \ "isDead").read[Boolean]
)(Creature)

And everything will work as expected. This syntax is a little convoluted, but you can think of it as "lifting" the constructor into the applicative functor for Reads, which allows you to apply it to the two Reads values for the fields. My answer here refers to Scalaz's applicative builder syntax instead of Play's, but they're essentially the same—just read |@| as and:

One part of the weirdness is that xs |@| ys doesn't really mean anything on its own—it's essentially an argument list that's waiting to be applied to a function that it will lift into its applicative functor and apply to itself.

See also my answer here and blog post here for additional discussion.


Need Your Help

Why is my mysql database timestamp changing by itself?

php mysql

Hey guys quick question, I have an entry that I put in my database, and as I echo the value, the value in the database stays the same while the data echoed keeps increasing, which is messing up my

What is the reason to get exit status value -1 in JSch

java ssh jsch

I am trying to run a command on remote Linux box from Java using JSch (SSH) api. The value of exitStatus is -1 [int exitStatus = channelExec.getExitStatus()]