jsonplayframework-2.0anorm

JSON deserializer for Anorm


First of all, I'm pretty new to Play 2 Scala. I'm trying to write a convert my model object to / from JSON.

As per this blog http://mandubian.com/2012/10/01/unveiling-play-2-dot-1-json-api-part2-writes-format-combinators/ This is what I have tried

    case class Facility(id:Pk[Int],name:String)

object Facility{

    implicit val facilityWriter = (
     (__ \ "id").write[Pk[Int]] and
     (__ \ "name").write[String]
)(unlift(Facility.unapply))

Then it gave me an error saying that no JSON deserializer found for Pk[Int]

So Ive tried something like this (after a bit of googling around)

implicit object PkFormat extends Format[Pk[Int]] {

    def reads(json:JsValue): Pk[Int] = Id(json.as[Int])
    def writes(id:Pk[Int]):JsNumber = JsNumber(id.get)
}

I don't understand what exactly is happening, and coudlnt find an example on how to serialize / deserialize anorm.


Solution

  • The JSON serializer/deserializer supports all the basic values that are covered by the JSON specification. If you want to serialize a custom type you have to tell the serializer how to do that.

    Play's JSON serializer uses a Scala (originally Haskell) pattern called type class. In a nutshell, it allows polymorphism without subclassing. This is achieved by bringing an implicit value in scope, i.e. to handle a new type, you define an implicit value/method/object. In your concrete example, you define a type class instance for Pk[Int].

    You could convert the Pk[Int] manually in your code, or as in many other frameworks implement the conversion in the Pk class directly, but the type class approach is cleaner (because JSON conversion is a separate concern) and easier to reuse (now you can convert a Pk[Int] anywhere you want even if the Pk class itself doesn't support it, imagine extending a closed-source system).

    As to your code, it should just work fine, just make sure you have the necessary imports in scope:

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