Manage your SailsJS server bootstrap code

Postman and SailsJS go hand in hand — SailsJS allows you to rapidly build API servers and Postman helps to manage, document, and test them as you go along. At Postman, the relationship is even deeper since we love to use SailsJS wherever we can.

One of the things that almost all servers invariably end up doing is to execute a bunch of tasks while they are starting up or restarting. We send a message to Slack saying that one of our server processes respawned. We also setup our internal encryption system, log some essential server information and setup the error reporting mechanism during server spawn.

SailsJS provides one bootstrap.js file to write all code that needs to be executed right before the server has been lifted. This is cool! But this also means that the bootstrap.js file could potentially become lengthy and convoluted if you are doing a lot of work during server start.

We decided to write a simple piece of code that would enable us to store a number of modules within a folder and run them during boot.

Our bootstrap.js file

/**
 * Bootstrap
 * (sails.config.bootstrap)
 *
 * An asynchronous bootstrap function that runs before your 
 * Sails app gets lifted.
 */
module.exports.bootstrap = function (callback) {
  // load all modules *Bootstrap.js in bootstrap directory 
  // and execute async
  async.eachSeries(_.values(require('include-all')({
    dirname: __dirname + '/../bootstrap',
    filter : /(.+Bootstrap)\.js$/,
    excludeDirs : /^\.(git|svn)$/,
    optional: true
  })), function (bootmodule, callback) {
    _.isFunction(bootmodule) && 
      (bootmodule(callback), true) || callback();
  }, callback);
};

This simple bootstrap function loads all files from the bootstrap directory in the server’s working-directory and executes all whose files whose filename ends in Bootstrap.js. With this, we can safely write individual files for separate server boot tasks and keep our codebase clean.

A boot module would be similar to how you implement SailsJS server policies. The module exports a function which receives a callback function as the first parameter. The callback function needs to be executed when the work in that bootstrap module is complete.

A sample Bootstrap module

Say we are writing a Bootstrap module that logs the server version as specified in package.json file.

/**
 * ServerStatsBootstrap.js
 * Bootstrap module to log server version from package file
 */ 
module.exports = function (done) {
  require('fs').readFile('package.json', function (err, data) {
    // exit if error in reading file
    if (err) {
      sails.log.error('Unable to read package. %s', err);
      return done();
    }
 
    // parse in try-block to avoid crash during parsing error
    try {
      // convert package file to JSON
      data = JSON.parse(data);
    }
    catch (e) { // when parsing error, exit
      sails.log.error('Unable to parse package. %s', e);
      return done();
    }
 
    // all ok, so log the package version
    sails.log.info('server version: %s', data.version);
    done();
  });
};

We use this to correlate exceptions on server with respect to the version of the server deployed and avoid regression issues.

To use bootstrap modules for your SailsJS server, simply replace ./config/bootstrap.js with our bootstrap file and store bootstrap modules in ./bootstrap/ directory.

If you liked this approach or have suggestions to make it better, feel free to drop in a line here or tweet @getpostman. Better still, if you want to be part of the Postman development team, drop us a mail at jobs@getpostman.com.

Comment

Your email address will not be published. Required fields are marked *


This site uses Akismet to reduce spam. Learn how your comment data is processed.