Wednesday, August 13, 2008

Automatic Serialization and Deserialization of JavaScript-Objects to JSON with Joose.Storage

One of the most useful features of Joose is the builtin role Joose.Storage which gives easy JSON serialization and deserialization to all Joose objects. All you have to do to use this role is to add
does: Joose.Storage
to your class definition like this:
Class("Point", {
does: Joose.Storage,
has: {
x: {is: rw},
y: {is: rw},
otherPara: {
is: rw,
init: "stuff",
persistent: false
}
}
})

Now if you use the json2.js library avaible from json.org you can also say:
Joose.Storage.Unpacker.patchJSON();
... and magically when you use the JSON library all Joose object will be serialized when you call JSON.stringify and will be deserialized (become Joose objects of the correct type) again when you call JSON.parse.

This makes round-tripping between JavaScript and JSON very easy. For example this creates a point then serializes it and immediately deserializes the point again.
var point = JSON.parse(JSON.stringify(new Point({x: 10, y: 20})));
alert(point.getX())
With normal JSON the resulting object will not have any methods but with Joose.Storage you get a real object of class Point.

The best thing about Joose.Storage is that it also works for deeply nested objects and it even preserves identity when an objects occurs within the same structure multiple times. In the above example the attribute otherPara of class Point is declared as persistent: false. This means that the attribute will not be serialized. This makes sense for attributes which can't be serialized like references to DOM elements.

Here is the resulting JSON document for a nested structure of points:
JavaScript:
var p0 = new Geometry.Point({x: 10, y: 20})
var p1 = new Geometry.Point({x: 20, y: 30})

var test = {
a: p0,
b: p0,
c: p1
}

Resulting JSON:
{"a":
{"__CLASS__":"Point",
"__ID__":5,
"x":10,
"y":20},
"b":
{"__ID__":5},
"c":
{"__CLASS__":"Point",
"__ID__":6,
"x":20,
"y":30}}

Joose.Storage is ideal for sending object to the server using and then creating them again at a later point. Joose.Storage is also wire compatible with MooseX::Storage which is a Perl module for serialization of objects and there are efforts under way to make it compatible with jsonpickle which is a Python implementation of a similar concept.
Post a Comment