I work with the Play JSON API (latest version, Play 2.4), reading incoming JSON in objects.
When writing JSON there is absolutely no problem using a list of custom objects , if I have one implicit val writes = Json.writes[CustomType].
But, obviously, the opposite is not true, since the following does not work, although it Readsis created for both the top-level type and the list type (using Json.reads[Incoming]and Json.reads[Item]). Is a regular Readsimplementation required? Or am I missing something obvious? What is the easiest way to make this work?
A simplified example:
JSON:
{
"test": "...",
"items": [
{ "id": 44, "time": "2015-11-20T11:04:03.544" },
{ "id": 45, "time": "2015-11-20T11:10:10.101" }
]
}
Models / DTOs corresponding to incoming data:
import play.api.libs.json.Json
case class Incoming(test: String, items: List[Item])
object Incoming {
implicit val reads = Json.reads[Incoming]
}
case class Item(id: Long, time: String)
object Item {
implicit val reads = Json.reads[Item]
}
Controller:
def test() = Action(parse.json) { request =>
request.body.validate[Incoming].map(incoming => {
// ... handle valid incoming data ...
}).getOrElse(BadRequest)
}
The compiler has something to say:
No implicit format for List[models.Item] available.
[error] implicit val reads = Json.reads[Incoming]
^
No Json deserializer found for type models.Incoming.
Try to implement an implicit Reads or Format for this type.
[error] request.body.validate[Incoming].map(incoming => {