How to implement implicit Json Writes of embedded object in Play Framework 2.x How to implement implicit Json Writes of embedded object in Play Framework 2.x json json

How to implement implicit Json Writes of embedded object in Play Framework 2.x


It's a question of visibility, when declaring the implicit Writes[Foo] you are not making visible the implicit Writes[Bar] to it:

scala> :paste// Entering paste mode (ctrl-D to finish)import play.api.libs.json._case class Bar(x: String, y: Int)object Bar {  implicit val implicitBarWrites = new Writes[Bar] {    def writes(bar: Bar): JsValue = {      Json.obj(        "x" -> bar.x,        "y" -> bar.y      )    }  }}case class Foo(id: String, bar: Bar)object Foo {  import Bar._  implicit val implicitFooWrites = new Writes[Foo] {    def writes(foo: Foo): JsValue = {      Json.obj(        "id" -> foo.id,        "bar" -> foo.bar      )     }   }     }// Exiting paste mode, now interpreting.import play.api.libs.json._defined class Bardefined module Bardefined class Foodefined module Fooscala> Json.prettyPrint(Json.toJson(Foo("23", Bar("x", 1))))res0: String = {  "id" : "23",  "bar" : {    "x" : "x",    "y" : 1  }}

Also, if you're using Play 2.1+ make sure to check out the brand new use of 2.10's macros: http://www.playframework.com/documentation/2.1.0/ScalaJsonInception

If you're happy with the use of the case classes and the val/vars' names being used as keys in the json output, as in your case BTW, then you can use the two one-liners:

implicit val barFormat = Json.writes[Bar]implicit val fooFormat = Json.writes[Foo]

That will give you the exact equivalent:

scala> import play.api.libs.json._import play.api.libs.json._scala> case class Bar(x: String, y: Int)defined class Barscala> case class Foo(id: String, bar: Bar)defined class Fooscala> implicit val barWrites = Json.writes[Bar]barWrites: play.api.libs.json.OWrites[Bar] = play.api.libs.json.OWrites$$anon$2@257cae95scala> implicit val fooWrites = Json.writes[Foo]fooWrites: play.api.libs.json.OWrites[Foo] = play.api.libs.json.OWrites$$anon$2@48f97e2ascala> Json.prettyPrint(Json.toJson(Foo("23", Bar("x", 1))))res0: String = {  "id" : "23",  "bar" : {    "x" : "x",    "y" : 1  }}