Scala 2.10, its impact on JSON libraries and case class validation/creation Scala 2.10, its impact on JSON libraries and case class validation/creation json json

Scala 2.10, its impact on JSON libraries and case class validation/creation


Forewords

Let me give a different solution that doesn't rely on any Java based library but only a pure Scala one.

Actually, as discussed in the comments of @Steve's results Play 2's scala version was using Jerkson for de/serializing Json to domain model. Where Jerkson is a DSL wrapper around a very good Java library for handling Json.

Answer

The above wasn't answering your question, since you were asking if it has been envisioned to used the reflection and the macro features of Scala 2.10 to ease this task!!!! By eliminating most boilerplates.

And it was a very good thought in fact because from the Play 2.1 version, the Json Scala API is not using Jerkson anymore but it's own mechanism.

This mechanism is in fact taking advantages of this new 2.10 version of Scala by introducing a brand new API based on two things:

  • a functional construction (Applicative Builder) adapted to be able to Read and Write Json or Domain instances. These builders are used to glue altogether combinators (for both read or write) in order to define coarse grained structured (like we do with Parser Combinators)
  • a bunch of macros that are able to discover which combinators are implicitly available and will construct complex ones for Case Classes (or at least types that have apply and unapply methods).

In the end of the day, here is what we could do by using this API:

import play.api.libs.json._import play.api.libs.functional.syntax._case class Person(name: String, age: Int, lovesChocolate: Boolean)implicit val personReads = Json.format[Person] //a format is a Reader and a Writer//this format will be implicitly used by the following from/toJson functionsval person:JsResult[Person] = Json.fromJson(json) //JsResult is like JsSucces/JsErrorval jsObject = Json.toJson(person)

code copied and adapted from: JSON Inception (Based on Scala 2.10 Macros)

A little note: the new API is even smart enough to be able to validate a "read" by accumulating errors...

References

There are a series of blogs from @mandubian that I'd recommend from here, because they are very enlightening it!

Final note

What is sad is that the modularization of Play 2... doesn't allow us to use this API alone! So, it should be used from the play lib as a whole :/This might change in the future...

EDIT

And the future is getting closer now, since Pascal has this repo enabling us to use the play-json API.

So, one can use this repo until Play 2.2 will be released. Indeed, this version will be completely decoupled with several APIs like json or iteratees, and thus, we'll be able to use the playframework repo directly.


Jerkson handles your use case today!

Json.generate(foo)

It also supports streaming reads and writes which we use extensively in production.

Json.generate(foo, outputStream)Json.parse[Foo](inputStream)

We originally used lift-json but its lack of streaming support for case classes made it unusable for reading and writing large json documents. Jerkson is also super fast and handles nested case classes perfectly.


Made a blog post about that, check it out at http://pedrorijo.com/blog/scala-json/

Using case classes, and Play WS (already included in Play Framework) you case convert between json and case classes with a simple one-liner implicit

case class User(username: String, friends: Int, enemies: Int, isAlive: Boolean)object User {  implicit val userJsonFormat = Json.format[User]}