Question

I've a bunch of case classes that I use to build a complex object Publisher.

sealed case class Status(status: String)
trait Running extends Status
trait Stopped extends Status


case class History(keywords: List[String], updatedAt: Option[DateTime])
case class Creds(user: String, secret: String)
case class Publisher(id: Option[BSONObjectID], name: String, creds: Creds, status: Status, prefs: List[String], updatedAt: Option[DateTime])

I want to convert the Publisher into a JSON string using the play JSON API. I used Json.toJson(publisher) and it complained about not having an implicit for Publisher. The error went away after I provided the following

implicit val pubWrites = Json.writes[Publisher]

As excepted it is now complaining about not being able to find implicits for Status, BSONObjectID and Creds. However, when I provide implicits for each Status and Creds it still complains.

implicit val statusWrites = Json.writes[Status]
implicit val credsWrites = Json.writes[Creds]

Any idea how to resolve this ? This is the first time I'm using Play JSON. I've used Json4s before and would like to try this using Play JSON if possible before I move go Json4s unless there are clear benefits for using/not using Json4s vs Play JSON.

Was it helpful?

Solution

The order of implicits are also important. From the least important to the most important. If Writes of Publisher requires Writes of Status, the implicit for Writes of Status should be before the Writes of Publisher.

Here is the code I tested to work

import play.modules.reactivemongo.json.BSONFormats._
import play.api.libs.json._
import reactivemongo.bson._
import org.joda.time.DateTime


sealed case class Status(status: String)
trait Running extends Status
trait Stopped extends Status


case class History(keywords: List[String], updatedAt: Option[DateTime])
case class Creds(user: String, secret: String)
case class Publisher(id: Option[BSONObjectID], name: String, creds: Creds, status: Status, prefs: List[String], updatedAt: Option[DateTime])

implicit val statusWrites = Json.writes[Status]
implicit val credsWrites = Json.writes[Creds]
implicit val pubWrites = Json.writes[Publisher]

val p = Publisher(
Some(new BSONObjectID("123")), 
"foo",
Creds("bar","foo"),
new Status("foo"),
List("1","2"),
Some(new DateTime))

Json.toJson(p)
//res0: play.api.libs.json.JsValue = {"id":{"$oid":"12"},"name":"foo","creds":{"user":"bar","secret":"foo"},"status":{"status":"foo"},"prefs":["1","2"],"updatedAt":1401787836305}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top