Sunday, February 19, 2012

Neo4J with Scala Play! 2.0 on Heroku (Part 4) :: Play 2.0/Json

Note

This post is a continuation of this post, which is the thrid part of a blog suite that aims the use of Neo4j and Play2.0 together on Heroku.

Play2.0 - Scala - Json

I'm about to write a quick wrap up, of some Play20's wiki entries and stackoverflow that were all related to Json in Play2.0.
For that, I'll take some usage examples, but also present the underlying libraries (Jerkson) and the used paradigm, SJson.

Scope

Giving that the wiki pages are really clean and self-explaining, I'm not gonna enter deeply in how Json must be used with Play 2.0 albeit I'll give some prerequesites in order to help you understand how I'll use the Neo4J REST API.

play.api.libs.json

This package contains everything you'll need in order to work with Json in Play 2.0.
It defines important structure like JsObject, JsArray and even some like JsUndefined.
They usage is very easy since they are based on classical scala's Map and List of JsValue(parent type).
Here is an example of creating a JsArray and iterating items. To test it in a REPL, I recommend you to enter the Play console by using play in your repo and the console in sbt (to have all libraries loaded).

For arrays, it's quite easy (maybe wrapping could be annoying but a little of pimping can resolve that).
The Jerkson library powerful comes with JsObject usages. It has defined a very clean DSL for querying Json. Here is an example for querying a property or catch a descendant property.

play.api.libs.json.{Format, Reads, Writes}

Until now, you saw that Json is usable with Play. But, I guess that you hope more than that, since this framework is here to ease the work.
And you're right.
Play is coming with a SJson flavor for serialization and deserialization of DSO.
Three traits come in the game.

Reads

Reads defines a simple method reads:
Having a Reads defined for a type T, we can now extract such instance from Json.
With the object Reads that defines an implicit Reads instance for most common types like Option, String, Short ...

Writes

Writes, like Reads, is very simple and defines a simple method writes:
Obviously, its purpose is to convert a value of type T into its Json representation and is the inverse function reads.
A Writes object is defined too with conversion to common types.

Format

This trait is there to put the pieces together
With the help of this trait, we can now have a serializer of custom domain object from/to Json.
A good practice is to define such Format into the companion object of your DSO, so that it will come in the scope at once when using it.
Here is an example:
Let's see how to use this Format easily to go back and forth from DSO instances.

play.api.libs.json.Json._

This object is an handy one, that defines four convenient methods. Two are here to play with String and JsValue. The other are to play with types and JsValue.
Back to our simple DSO class, we can now do this:

Enhancement

In order to have more control on effects of your serialization, I would recommend you to consider the Scalaz library's Validation construct.
Indeed, it will help you having more relevant information and all at once if you reads is wrong.
Here is a talk about this (but not in Play).

In the next post, we'll talk about the Dispatch library. See it here