ruk·si

🟢 Node
Application Design

Updated at 2015-07-25 16:41

Keep your application stateless. Have a mindset that the server may crash at any time. It's not that node crashes a lot but it's the mindset that allows you to create horizontally scalable web services. Makes scaling effortless in the future. Use e.g. Redis to keep state if required.

Test your code. Define your testing harness before you write even one line of code.

Write small functions. Optimal size is about ten lines.

// bad
function convertJsonToCsv(filename, target, callback) {
  readFile(filename, function(err, content) {
    if (err) {
      return callback(err);
    }
    parseJson(content, function(err, data) {
      if (err) {
        return callback(err);
      }
      convertToCsv(data, function(err, csv) {
        if (err) {
          return callback(err);
        }
        writeFile(target, csv, callback);
      });
    });
  });
}

// good
function convertJsonToCsv(filename, target, callback) {
  readJsonFile(filename, function(err, data) {
    if (err) {
      return callback(err);
    }
    writeCsvFile(target, data, callback);
  });
}
function readJsonFile(filename, callback) {
  readFile(filename, function(err, content) {
    if (err) {
      return callback(err);
    }
    parseJson(content, callback);
  });
}
function writeCsvFile(target, data, callback) {
  convertToCsv(data, function(err, csv) {
    if (err) {
      return callback(err);
    }
    writeFile(target, csv, callback);
  });
}

Avoid this and prototype. Especially if you are not fully sure how they work. They tend to create confusing syntax where simpler solutions would do a lot better.

// bad
function DB(url) {
  this.url = url;
}

DB.prototype.info = function(callback) {
  http.get(this.url + '/info', callback);
};

async.parallel([
  function(cb) {
    new DB('http://foo').info(cb);
  },
  function(cb) {
    new DB('http://bar').info(cb);
  }
], ...);

// good
function DB(url) {
  return { info: async.apply(http.get, url + '/info') };
}

async.parallel([
  DB('http://foo').info,
  DB('http://bar').info
], ...);

// making all arguments explicit
var dbInfo = function(url, callback) {
  http.get(url + '/info', callback);
};

async.map(['http://foo', 'http://bar'], dbInfo, ...);

Avoid extending prototype of native objects. May possibly cause problems with other libraries.

// bad
Array.prototype.empty = function() {
  return ! this.length;
}

Sources