Common path prefix in Play framework 2.2.x scala JSON Reads

I would like to only read "value" from the following JSON

{
  "field": "feed",
  "value": {
    "item": "post",
    "verb": "add",
    "post_id": 1234568567515,
    "sender_id": 10200718414514
  }
}

into this:

case class Value (
  item: String,
  verb: String,
  itemId: Long,
  senderId: Long
)

The Reads[Value] looks like this:

implicit val valueReads: Reads[Value] = (
  (__ \ "item").read[String] and
  (__ \ "verb").read[String] and
  (__ \ "post_id").read[Long] and
  (__ \ "sender_id").read[Long]
) ( Value )

How can I specify the common parent node "value" for all the paths in Reads without repeating it all over the place like (__ \ "value" \ "item"), (__ \ "value" \ "verb") etc.?

Answers


This code seems to work:

implicit val valuereads = (__ \ "value").read {
  ((__ \ "item").read[String] and
   (__ \ "verb").read[String] and
   (__ \ "post_id").read[Long] and
   (__ \ "sender_id").read[Long] 
   )(Value.apply _)  
}

Not sure if it is what you are looking for, but if you want skip manually writing Reads objects, you can use macros. But for that case you should have parent case class, which will have inside two fields: field and value.

So it'll be something like:

case class Value (
  item: String,
  verb: String,
  itemId: Long,
  senderId: Long
)

case class MyClass(field: String, value: Value)


implicit val myClassReads = Json.reads[MyClass]
implicit val valueReads = Json.reads[Value]

So at the end you can get your value from the MyClass object.


Need Your Help

Using Guava's EventBus, possible to run subscriber code on thread that created the bus?

java android multithreading guava

Using Guava's EventBus, I want to be able to post from a background thread (called "background") to a specific thread (in this case, thread "main") that updates the UI. I thought the following woul...