简体   繁体   中英

Play framework - Writes partial object

I have the following object:

case class A(id: Long, name:String, lastName:Option[String], age:Int)

I want to use Writes convertor to write only part of this object. So I tried this code (trying to write the object without the age):

implicit val aWrites: Writes[A] = (
  (JsPath \ "it").write[Long] and
  (JsPath \ "name").write[String] and 
  (JsPath \ "lastName"). writeNullable[String]
)(unlift(A.unapply))

But this obviously doesn't compile. Is there a way to make this work?

You can do this, but you can't reference A.unapply . Part of the conciseness of JSON combinators comes from the apply and unapply methods that are automatically generated by the compiler for case classes. But these methods use all of the parameters in the class.

A.unapply has the signature A => Option[(Long, String, Option[String], Int)] . This is incompatible with combinators that only cover three fields (instead of all four). You have two options.

1) Write another unapply -like method that has the correct signature:

def unapplyShort(a: A): Option[(Long, String, Option[String], Int)] =
    Some((a.id, a.name, a.lastName))

implicit val aWrites: Writes[A] = (
  (JsPath \ "id").write[Long] and
  (JsPath \ "name").write[String] and 
  (JsPath \ "lastName").writeNullable[String]
)(unlift(unapplyShort))

2) Manually create the Writes as an anonymous class:

implicit val aWrites: Writes[A] = new Writes[A] {
  def writes(a: A): JsValue = Json.obj(
    "id" -> a.id,
    "name" -> a.name,
    "lastName" -> a.lastName
  )
}

Option 1) from @mz can be put more succinctly as:

implicit val aWrites: Writes[A] = (
  (JsPath \ "id").write[Long] and
  (JsPath \ "name").write[String] and
  (JsPath \ "lastName").writeNullable[String]
)((a) => (a.id, a.name, a.lastName))

FYI, you can achieve that like the following. (This is just a suggestion.)

object noWrites extends OWrites[Any] {
  override def writes(o: Any): JsObject = JsObject(Seq())
}

implicit val aWrites: Writes[A] = (
  (JsPath \ "id").write[Long] and
  (JsPath \ "name").write[String] and
  (JsPath \ "lastName").writeNullable[String] and noWrites // <---
)(unlift(A.unapply))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM