My JavaScript book is out! Don't miss the opportunity to upgrade your beginner or average dev skills.

Thursday, March 14, 2013

Solving Cycles, Recursions, And Circulars References In JSON

CircularJSON is my next level take on @getify thoughts about recursive-safe JSON.stringify() operation, going further than what @izs proposed with his json-stringify-safe module which aim, and purpose, can be summarized in his reply:
This module is useful for the use case I'm using it for. If it's not your cup of tea, well, GOOD NEWS! There are a lot of cups with a lot of different flavors of tea in them.
Thanks man, what you probably don't know is that actually, there are no concrete, safe, performant, solutions to that problem ... oh well, now there is one!


My fully tested, 650 bytes, portable and cross platform solution, is based on same isaacz logic: the usage of JSON.stringify(data, receiver)
In few words, if you consider safe the native JSON, you can consider safe CircularJSON too in both serialization and deserialization.
Despite what you might think about recursive serialization, there's no magic behind and all tests can prove that CircularJSON is simply safe and working as you expect.

How Can Be That Safe

THe logic behind is based on native JSON behavior where the receiver and the reviver functions are all CircularJSON uses in order to work.
For the end user, same JSON API is preserved and it works as expected so nothing is different, except circular references are recreated during parse operation.
Once again, not a rewritten parser, neither a RegExp based solution, CircularJSON is the simplest solution to the most common circular, recursion, repeated object, problem.

How About Performance

This is tricky, and you can test performance via node test/benchmark.js and compare results in your machines and with your node version.
Generally speaking, performance is about twice as slow as regular JSON but only with never repeated data.
That's correct, as soon as there are repeated objects in the serialization and deserialization process, CircularJSON goes faster until being faster than JSON when there are more repeated objects in the stream.
I am obviously excluding cycles and circular references from the game since we all know JSON will simply fail, don't we?

Why Solving Circular References

First of all, because we are developers. If there are circular references it probably means we needed them, right? As summary, in my opinion, any attempt to get rid of circular references because of serialization is a failure for the simple fact that once deserialized, we canot have that reference back anymore.
THere could be cases we need circular references and as PHP, as example, solved them since ever through serialize() and unserialize() function, we might want to do the same via JavaScript: why not?!

Do Not Mix Shit!

While @izs thinks I am a moron noob, Kyle insinuated something could go wrong ... well, GOOD NEWS IS, they are both wrong as long as you don't use CircularJSON.parse() with data that has been encoded with JSON.stringify() and of course, the same is valid the other way round: do not .parse() via JSON what has been encoded via CircularJSON ... it's like using JSON to decode PHP serialized strings or vice-versa ... you know what I mean?

Welcome To Other Languages

As the fact it has been implemented in multiple programming languages helped JSONH to be that successful, and before, of course, JSON protocol itself, once many other programming languages in both client and server will be able to be compatible with circular references this project could be more widely adopted, specially to those that do not use node.js as server side solution.
Long story short, you are welcome, and thank you in advance, for any other language implementation you might want to push in this repository. Enjoy!

No comments: