evermean
evermean

Reputation: 1307

Serialize only specific attributes using Writes trait with unapply

Lets imagine I have a case class like this:

case class Product(ean: Long, name: String, description: String)

and I want so serialize objects of this class to Json, I can implement the Writes trait like this:

implicit val productWrites: Writes[Product] = (
  (JsPath \ "ean").write[Long] and
  (JsPath \ "name").write[String] and
  (JsPath \ "description").write[String]
)(unlift(Product.unapply))

This works fine if I want to serialize all the attributes of the object. Now lets say I don't want to serialize the ean. I tried something like this:

implicit val productWrites: Writes[Product] = (
  (JsPath \ "name").write[String] and
  (JsPath \ "description").write[String]
)(unlift(Product.unapply))

This doesn't seem to work since one needs to use all the fields/attributes that the unapply method returns.

Is there a way to make the second serialization method work with only the attributes that I want to serialize or do I have to use something like this:

implicit object ProductWrites extends Writes[Product] {
  def writes(p: Product) = Json.obj(
    "name" -> Json.toJson(p.name),
    "description" -> Json.toJson(p.description)
  )
}

Is this the only way?

Upvotes: 1

Views: 106

Answers (2)

kawty
kawty

Reputation: 1656

unlift(Product.unapply) has a type Product => (Long, String, String).

In this case, the argument should have a type Product => (String, String). You can write a function literal like following.

implicit val productWrites: Writes[Product] = (
  (JsPath \ "name").write[String] and
  (JsPath \ "description").write[String]
)(p => (p.name, p.description))

Upvotes: 3

Knut Petter Meen
Knut Petter Meen

Reputation: 44

I think your last example is the way to go. Here's another way of doing the same thing using an implicit val instead of an implicit object:

implicit val productWrites: Writes[Product] = Writes { p =>
  Json.obj(
    "name" -> Json.toJson(p.name),
    "description" -> Json.toJson(p.description)
  )
}

Upvotes: 1

Related Questions