Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Noise-free JSON processing with Scala

Tags:

json

scala

dsl

I'm coming from a dotnet land, but recently have been looking at the possibilities of alternative programming languages. Nothing really serious, just some bits here and there. Recently I've discovered Scala and I'm pretty fascinated with it. Despite non-deterministic tinkering, I've done some intermediate checks of stuff that is important for me in C# and I feel rather satisfied: functional notions - tick, ad-hoc polymorphism - tick, annotations - tick, reflection and codegen - tick.

Now I'm thinking about how one would program an analogue of JSON processing library I've implemented in C# 4.0 with the help of DLR and "dynamic" syntactic sugar. Here's the feature set I'm looking for:

  1. Convenient browsing and construction of raw JSON.
  2. Automatic conversion between JSON and native objects/collections (in its general form the problem is unsolvable, though one can define conventions that will work 95% of the time - and that's fine for me).

New features of C# 4.0 kinda rock here, since they let me override member access and type casts to perform completely custom logic (if a variable in C# 4.0 is typed as "dynamic", then anything you do with it will be compiled into calls to programmer-defined methods with reasonable default behaviour - see DynamicMetaObject.BindXXX methods at MSDN for more info). E.g. I've overriden type casts to serialize/deserialize .NET objects and member accesses to manage raw JSON, so that I can write the following code:

var json = Json.Get("http://some.service");
if (json.foo) Console.WriteLine((Foo)json.foo);
json.bars = ((List<Bar>)json.bars).DoSomething();

Of course, this is not ideal, since dynamic binding in C# 4.0 has problems with extension methods and type inference, and, moreover, the code still feels rather heavyweight. But anyways, this is much better than using all those ((JsonObject)json["quux"])["baz"] I've used to in c# 3.5.

Some basic research shows that Scala doesn't have dedicated language features that support late binding. However, there are so many tricks that maybe they can be used together to create a bearable emulation of the code shown above (or even to be better - I almost sure that this is possible). Could you, please, advise me something here?

like image 783
Eugene Burmako Avatar asked Nov 01 '10 00:11

Eugene Burmako


3 Answers

A useful JSON library for Scala is lift-json, which is a standalone component of the Lift Web Framework.

https://github.com/lift/framework/tree/master/core/json

It supports extraction to classes, parsing and a DSL for creating JSON.

The page I linked to has a comprehensive tutorial, so I won't just copy and paste it.

like image 200
tylerweir Avatar answered Sep 20 '22 05:09

tylerweir


You should definitely have a look at sjson. Here -> sjson on github I'm using the Type class based implementation, which you can peruse here -> some examples If you have a jaunt through the code, there's some really interesting scala tricks. This should give you what you're looking for in regards to #2. SJSON wraps dispatch-json which I believe provides integration to lift-json (mentioned above). Both dispatch-json/lift-json should give you what you're looking for in #1. For what its worth I've been using sjson in a large project and its going swimmingly. And the gentleman behind the project has been pretty amazing and supports the project very well.

like image 29
Vonn Avatar answered Sep 23 '22 05:09

Vonn


I've floated between using lift-json and various variants of sjson (e.g. dabasishg/sjson) and more recently Jerkson (a Scala wrapper on Jackson).

For the purposes of object serialization and deserialization I keep on finding Jerkson to require the least tweaking to get a job done, for example, I've just been coding a simple object serialisation with a case class that looks like this:

import org.joda.time.LocalDate

case class UserStatus(subscriptionEndDate: LocalDate = null)

I had various errors with both lift-json and sjson but jerkson just worked with:

import com.codahale.jerkson.Json

val jsonString = Json.generate(statusObject)

and

val newObject = Json.parse[UserStatus](jsonString)
like image 22
sroebuck Avatar answered Sep 19 '22 05:09

sroebuck