Is there a better way to accept JSON data than appending chunked input to a string and running `JSON.parse()` upon it afterward?

Is there a better way, in Node.js, to accept JSON data than appending chunked input to a string and running JSON.parse() upon it afterward? The server can not assume that the JSON input is valid, and JSON.parse() is the only way I'm aware of to validate JSON data.

Assume the following server accepts:

  • only POST requests
  • only JSON data
  • only with a Content-Type header of "application/json"

.

var server = http.createServer(function(req, res) {
    ....

    var parsedData;
    var inputData = '';

    req.on('data', function(chunk) {
        inputData += chunk;
    });

    req.on('end', function() {
        parsedData = JSON.parse(inputData);
    }

    ....
}

If I am enforcing the input data so strictly, it seems strange to simply append this data to a string and then JSON.parse() it, essentially (assuming proper JSON is inputted) going JSON -> string -> JSON. (Of course, one can not assume the data is valid.)

What you're doing is fine really. However, a performance tweak might be to just add each chunk to an array and then join the array instead of creating a new string each time.

e.g.

var inputData = [];
var parsedData;

req.on('data', function(chunk{
    inputData.push(chunk); //assuming chunk is from utf-8 stream, if not call chunk.toString()
});

req.on('end', function(){
    try {
       parsedData = JSON.parse(inputData.join(''));
    } catch (err) {
      //handle error    
    }
});

This way you are not reallocating and creating a new string each time with inputData += chunk. Note, this is fine for expected small inputs as V8 optimizes this case quite well.

Now, on the note of bad JSON. You do have options that you may want to look at.

  1. JSONStream - I'm not quite sure how this handles parsing errors, but it's quite nice for large JSON input.

  2. json-scrape - This does really well at filtering out bad input that isn't JSON.

Hopefully this info helps some.