Using a singleton module for config data


By Pedro Teixeira

This is the sixth article from a new series about Node.js. In the previous articles we talked about flow control: how to use callbacks, event emitters andstreams.

In this article we’ll start covering a new subject: configuration. Enjoy!

- Pedro Teixeira

(Some of the code samples in this article you can find in this github repo).

Most applications need configuration data. Here are some examples of what I mean by configuration data:

  • Database server hostname and port
  • Database server credentials (username and password)
  • Server TLS certificate
  • HTTP service URL
  • API key for email delivery service
  • Client secret for Twitter application
  • The usernames that are not allowed for public registration

As you can see, some of this data is secret and should remain secret. Other data can be made public without problems.

This data can either be hard-coded (and spread out inside your code), or live somewhere else. Your code will always have assumptions: it assumes what a given response from the Twitter API looks like; and it assumes that the user data lives in a CouchDB server. The trick is to balance what is configuration and what is code.

A Singleton module that exposes conf data

One common pattern is to have one file or directory where all the configuration data lives. This file can be a simple JavaScript file that just exports some values like this:

config.js:

exports.couchdb = {    
  url: 'http://my.couchdbserver.local:5984',  
  admin\_username: 'admin',  
  admin\_password: 'admin password'  
};
exports.forbidden\_usernames = \['root', 'admin', 'staff', 'ceo', 'chief', 'moderator'\];

Then the other modules of your application that need configuration data just need to do this:

var config = require('./config');    
// use config.couchdb.url

Using a façade module

This approach is not particulary scalable though: as the amount of configuration grows, maintaining one file with all this data can get ugly. An alternative is to have a directory where all the configuration is stored with an index.js file to collect it all:

config/index.js:

exports.couchdb = require('./couchdb');    
exports.forbidden\_usernames = require('./forbidden\_usernames');

Each one of these files can be a JavaScript or a JSON file: if you omit the file extension, require will look for a file with a .js or a .json extension.

The rest of your code that needs the configuration values can remain the same as before — Node picks up the index.js as the default file for a given directory:

var config = require('./config'); // defaults to ./config/index.js

Next Article

In the next article we’ll be talking about environment variables and how you can use them in Node.js to define configuration values in your application.

Written by Pedro Teixeira — published for YLD.

Interested in Node? Read more about it:


Written by YLDJanuary 4th, 2016


Share this article