While playing around with the Play! framework today, I stumbled upon the somewhat clunky JSON integration for reading the body of an HTTP request. The recommended approach of using type safe JSON and browsing the tree while creating your custom object or using a Format seems quite cumbersome for most standard situations that the standard libraries Jerkson and Jackson (included in Play!) handle gracefully. In this blog I will describe an approach that uses a custom BodyParser to come to a simpler solution.

The recommended approach of writing an action that processes JSON is to write a Format for your case class, like this:

On line 6 the Format is used implicitly to convert the Person objects to JSON. On line 10 the default JSON parse is used in the action. On line 11 the parsed body is converted to a Person using the Format again implicitly and passed to the rest of the application.

This looks quite ok, but when you have a large number of classes with many fields, writing all the Formats becomes quite cumbersome. Especially considering that the Jerkson library, that is underneath all this, already support straight forward Object to JSON mappings that will suffice in most situations.

For standard situations it would be simpler to not have to write a Format at all. This can be achieved by using a generic body parser like this:

Comments (3)

Although the reflection based solution can be very convenient I often find it brittle:

- You often end up with class cast exception. For example, when running continuous test in sbt (~ test).
- You have little insight into what data is being serialized and what the actual format is. This is especially troublesome if you have nested fields of types that need special serialization (UUID or your own simple value classes). You'll need to register these with the reflection framework, but you'll often forget, which means you may be stuck with some incomprehensible format (I've seen this while using XStream and java.net.URI, before they added a customer converter).

Fully agree that for more complex cases, you want more control and insight into the conversion to and from the JSON format. And then compile time errors are very nice.
For simple cases though, the JSON format is easily determined from the Scala/Java classes and the reflection based convertors usually do the right thing.

It is good to be able to choose for a simple or complex solution/implementation.

Thanks for the well explained example. However I have a little disclaimer: when you define your models to wrap mapped json, you are using "case class".
Are you aware of the 22 arguments limit restriction. Most likely, when you are working with nested json, you will hav large amount of data.
So, did you came across this exception. In case you did can you please share your best tips to get throught it, thanks.