Lost in translation - Node.JS

Despite the ease with which you can get a server coded in javascript (regardless of whether the actual code-running facility is C or anything else) still begs  the question: Should you write a server in JavaScript? To really get a handle on the answer to this question, consider a pretty typical use case.

The JSON round trip

It is a clustered pub-sub system, with zero points of failure.

You’ve got a typical web application, HTML front-end with CSS styling, and JavaScript for the validation and communication with a server. And because you’re up on the interactive web, you’re using Ajax and not relying purely on a form’s POST to get data to and from the server. If this is you, then you’re probably comfortable with JSON, too, as that’s the almost de facto means of sending data across the wire these days.

So you’ve got an Ajax request that says, for example, “give me more information about some particular guitar on an online auction site.” That request gets thrown across the network to a PHP program running on a server somewhere. The PHP server has to send a lot of information back to the JavaScript requestor, and it’s got to send that information in some format that JavaScript can unpack. So the return information is bundled up into an array, which can then be converted to JSON, sort of like this:

$itemGuitar = array( 'id' => 'itemGuitar',
'description' => 'Pete Townshend once played this guitar while his own axe ' . was in the shop having bits of drumkit removed from it.',
'price' => 5695.99,
'urls' => array('', '') );
$output = json_encode($itemGuitar); print($output);

Back on the client, the JavaScript gets this chunk of information, which has changed slightly because of JSON and transmission. The client basically gets something like this:

"id": "itemGuitar",
"description": "Pete Townshend once played this guitar...",
"price": 5695.99,
"urls": ["", ""]

This is pretty standard fare. Then, it’s easy to convert this text “thing” into an object in JavaScript. You just call eval(), like this:

var itemDetails = eval('(' + jsonDataString + ')');

The result is a nice JavaScript object with properties that match up to the JSON array-like structure. Of course, since the jsonDataString usually is returned from a server, you’re more likely to see code like this:

var itemDetails = eval('(' + request.responseText + ')');

This is the typical JSON round trip. But there are problems here … big, big problems.

Subtlety and nuance destroy solid code

First, there’s a major problem in that, this sort of code relies heavily on a translator. In this case, the translator is the JSON interpreter and related code, and there are in fact two dependencies: a JSON interpreter for Java in the form of what eval() does with the response text, and the JSON interpreter for PHP. As of PHP 5.2.0, that interpreter is included with PHP, but it’s still essentially an external dependency, separate from the core of PHP.

Now, this isn’t a rant about translation itself. There’s nothing to suggest that there are problems in taking, say, an “I” and turning it into an “i”, or something that’s item 1 in an array and reporting it as being item 2 in an array. There’s a lot of testing that occurs before JSON tools are ever released to ensure that what gets reported is correct, and accurate round tripping from a client to a server and back again are possible. Lots and lots and lots of testing is involved …And that is in fact a problem.

The dependency of JavaScript and PHP (and C and Lisp and Clojure and Eiffel and …well, see the figure below for all the JSON toolkits floating around, for a ton of different languages) on a toolkit is a huge issue. In other words, the problem isn’t the translation, but the translator. While programming languages evolve slowly, the uses to which these languages are applied is growing quickly. The result is that JSON is being put to use in areas of complexity that simply didn’t exist or went untouched even a few months ago. And with each new iteration — each new depth of recursion and combination of data types — it’s possible that an area is discovered that the translator doesn’t support.


A selection of JSON toolkits.

That’s not in itself bad. In fact, it argues for the popularity of JSON that it’s constantly put to new use. But with the “new” comes the “does it support the new?” So JSON has to evolve from time to time, and that means testing, and retesting, and release on tons of platforms. You, the programmer, may have to rearrange your data; or wait on a release to support your needs; or hack at JSON yourself. Again, many of these are just the so-called costs of programming.

But imagine you could ditch the translation — and therefore the translator — altogether. Imagine you could write, not JSON round tripping, but JavaScript end to end.

That’s the promise of Node. All the text you’ve just read — about PHP including JSON in 5.2.0 but not before, about arrays, becoming objects, about data being configured in new ways and requiring new things from JSON — it all goes away when you have JavaScript sending data and receiving and responding to that data.

eval() in JavaScript is (Potentially) the Devil
As if that’s not enough reason to look seriously at Node, there’s this pesky issue of running eval() on a string. It’s long been accepted that eval() is dangerous stuff. It runs code that you can only see as textual data; it’s the equivalent of that “Run Your SQL by typing it in here” unvalidated text box, open to SQL injection and malicious intent. It’s quite possible that every time eval() is passed in a string, a puppy somewhere in the Midwest shivers and a mom on the Eastern Seaboard stubs her toe and curses. It’s that precarious. There’s plenty to read about online, and it’s not worth going into in detail here. Just Google “eval JavaScript evil” or “eval JavaScript injection” to get a good taste of the issues.

Still, Node without any context doesn’t allow you to avoid eval(), so there are potentially still shivering puppies out there. However, Node used as it’s intended absolutely gets you around the typical eval() problems. Node is often called evented JavaScript or evented I/O, and that little word — “evented” — is hugely important. But to get a hold of what evented really means, and why it gets you out of the dangers of eval(), you’ve got to understand not just how JSON is typically round tripped in applications, but how the very structure of applications on the web are typically architected.


Get Updates on Tech posts, Interview & Certification questions and training schedules