One of the more interesting features of LoopBack I’ve been meaning to take a look at is its support for “environment configuration”. This is a fancy way of saying “configuration based on environment.” I’m still a Node newbie, but this is something I’ve done myself for a while now. Once again, LoopBack really shines here in doing some of the boilerplate code for us. The docs go into great detail about this feature, but I thought a simple example might be useful.

First, a reminder. LoopBack uses JSON files for various different configuration settings. In every case where there’s a JSON file, you can swap it out with a regular JavaScript file to enable dynamic configuration instead. So for example, datasources.json can also be datasources.local.js. (Note – in this case, “local” isn’t referring to any environment. The requirement for the word “local” in the file may go away soon.) This allows you to define the same values the JSON file does – but with JavaScript code. This could be useful for dynamically creating a datasource at run time. (This could lead to some fancy scenarios – so for example, trying to connect to a main database and if that fails, use a backup.)

Along with supporting a .local.js file, you can also provide support for environment specific configuration files, both in JSON and JS format. By checking the NODE_ENV environment variable, LoopBack will automatically load a matching *.ENV.json or *.ENV.js file. To make it more specific, given a datasources.production.js file, this will be matched in a production environment versus datasources.development.json.

As a LoopBack developer, I have a few options. I could use the local file as a default, or use a file specific to development. I can also decide between simple, static configuration with a JSON file versus a more dynamic JS file. In production, I can make the same choice.

To help make this more clear, I’ve created a demo. You can find the full source for this demo here: https://github.com/StrongLoop-Evangelists/demo-lb-env.

I began by creating a new LoopBack application with the default Notes modal and in-memory datasource. I decided that I’d use the in-memory datasource in my local environment and a Cloudant datasource when I deployed the application to Bluemix. As an aside, while LoopBack has an “ORM-like” data abstraction layer that makes stuff like this possible, typically I’d probably recommend against having different types of datasources in development versus production. Instead, I’d setup a local CouchDB instant instead. But it worked – so I’m going with it now. I made one small tweak to the local datasource – and that was to add a file property to it:

{
  "db": {
    "name": "db",
    "connector": "memory",
	"file":"data.db"
  }
}

The next thing I did was to create a new model. I named it Cat because, of course I did. I didn’t do anything fancy with this model – I just specified three simple properties: name (string), age (number), and friendly (boolean).

Finally – I ran my local server, ensured everything was working as normal, made a new cat, and confirmed I could fetch it with a Get request:

The next step was to create a new Node.js application in IBM Bluemix. After creating the application, I then provisioned a free-tier instance of our Cloudant service. Finally, I launched the web-based admin for Cloudant and created a database called “data”. (Very imaginative, I know.) I provisioned my server with everything I needed at this point. I just had to tell LoopBack how to use it.

Back on my machine, I began by adding the connector for Cloudant:

npm install --save loopback-connector-cloudant

Next, I created a new file, datasources.production.js. The JS extension lets us know we’re doing something with code here versus just simple configuration. By default, Bluemix puts all of your server data into an environment variable called VCAP_SERVICES. If you forget what this looks like, you can select the “Runtime” link in Bluemix and then the “Environmental Variables” tab.

I then wrote my code to setup the datasource dynamically. Note that I used the same name, “db”, for my datasource. This is important since LoopBack associates a model with a particular named datasource.

var env = JSON.parse(process.env.VCAP_SERVICES);

module.exports = {
	db:{
		connector:'cloudant',
		url:env['cloudantNoSQLDB'][0].credentials.url,
		database:'data'
	}
}

And that was it. I pushed my code up to Bluemix and confirmed that I had different data when performing requests. Here’s a cat I made in production:

[
  {
    "name": "cloudant cat",
    "age": 2,
    "friendly": true,
    "id": "078ea0a0c1ff33c09623c24e2daddabe"
  }
]

Now I’ve got a LoopBack app that can use a development datasource on my local machine and automatically switch to production when pushed up to Bluemix. I don’t have my credentials hard-coded anywhere which means that if I need to reprovision the Cloudant instance, I probably will not have to touch any code!

What Next?

  • Try out LoopBack, the highly-extensible, open-source Node.js framework.
  • Then, read this blog post by Raymond Camden and learn about file storage and LoopBack.