Move with MongoDB & Node.js onto the Cloud (Beginners Guide)

In this 2nd part of our blog-tutorials, we will connect the existing Node.js app with a MongoDB and deploy it onto the Cloud.

This blog post refers to the first blog in this series – Push your first Node.js app onto the Cloud. It would be useful if you referred to this blog and tutorial before continuing here.

mongodb-logo-web-tagline-99280fe76cc002a93d023901c1a05df8b621f1c893084a580dee83de9be96630In this 2nd part of our blog-tutorials, we will connect the existing Node.js app with a MongoDB. MongoDB is a NoSQL database, which
saves content in JSON-like documents and dynamic structures. The first release of MongoDB was in 2009 and since then, this database has seen a tremendous growth in usage in various places – mainly applied in non-transactional but specifically in web-related environments. Learn more about MongoDB on wikipedia or directly on the MongoDB website.

 

Install and prepare a MongoDB

To start, first install a local MongoDB. This provides you with the ability to “play around” so that you can get a good idea of the actual workings of an noSQL database.

  1. Download & Install
    Visit www.mongodb.org/downloads to download and install MongoDB onto your local machine. Details on how to install it on your system can be found within the following documents:
    Windows | Linux | MacOS X
  2. Prepare your Data folder
    First; create a folder where you wish to save your database. For instance, create a folder like /mdata/db on Unix based systems or C:\mdata\db for Windows based systems.
  3. Starting your Database
    For OS X: MongoDB, in all likelihood, automatically gets added in the Path env. Therefore, you can simply open a console and start the service:

    mongod --dbpath /mdata/db

    For Windows: Open a command line and navigate to the MongoDB installation.  With version 3.0, the common folder is “C:\Program Files\MongoDB\Server\3.0\bin>”. Start your MongoDB for the first time by specifying where your predefined database folder is located:

    C:\Program Files\MongoDB\Server\3.0\bin>mongod --dbpath c:\mdata\db
  4. Connect to your Database
    Start a new command prompt/console and the Mongo-client. It is also located in the same folder as the MongoDB (i.e. “C:\Program Files\MongoDB\Server\3.0\bin>” on Windows and can be directly accessed by launch-able on OS X;

    mongo

    This connects you directly to your local running database;

    connectingLocal

    Now, data can be added. In order to perform this, select your destination database. This will directly create your Database:

    use weatherDB

    You are now in the “not-yet-existing” database weather. Let us insert some data:

    db.weatherCOLL.insert({"temperature" : "cold"});

    And yes, this can be directly typed into the console and should provide feedback which appears somewhat like “nInserted” : “1”;

    step02

    So far so good, you just installed a local MongoDB, added a weather database with some JSON content referring to cold temperature; time for some warm chocolate 😉

    Note that you can find further information and very handy tutorials about MongoDB on docs.mongodb.org. In addition, some very useful reference cards with commands and can be found easily at: quick-reference cards.

 

Connect your Node.js App

Now we can connect our Node.js App which we started developing in our last blog with the new local MongoDB.

To allow a connection from Node.js to MongoDB, in general, we require a database library. We will use the default mongodb-library which is the default MongoDB library. (Hint: better drivers exist such as ODM ones which are available, however, for now will keep it simple and choose the default one)

  1. MongoDB Driver
    In order to add a driver, please extend the package.json file you created the  last time with the highlighted line:

    {
      "name":"nodejs123-example",
      "version":"0.0.1",
      "author": "Demo",
      "dependencies": {
        "express": "4.13.3",
        "mongodb": "2.1.0"
      },
     "scripts": {
     "start": "node app.js"
     }
    }

    This will notify NPM (the node packaging) to obtain the correct library before starting the App. Following this, perform an already know command to ensure all modules are downloaded.

    npm install

    This will install all required dependencies for the use of MongoDB within Node.js.
    It is important to note that, you will probably receive some ugly ERROR messages (especially on Windows), such as:
    step03
    Calm down! You can ignore them for the moment until you make use of encryption features such as Kerberos in the future. For the purpose of this “hello-weather” demo, this is not a problem and we are totally fine so can continue!

  2. Let’s jump into code
    Now let’s enhance your app. Open the app.js file with an editor and replace the existing res.send(…) line with the following code-snippet:

    var express = require('express'); // Webframework for Node.js, quite powerfull
    var app = express(); 
    var mongoClient = require('mongodb').MongoClient; // New MongoDB client
    
    /*
     * Gather  all requests from / 
     */
    app.get('/', function (req, res) { // telling nodeJs to get all commands from / into this function
        /* Connect to MongoDB */  	
    	mongoClient.connect( "mongodb://localhost:27017/weatherDB" , function(err, db) { // connect to the local Database
    		res.writeHead(200,{"Content-Type" : "text/html"}); // write header
    
    	  	res.write('<h1>How is the weather ? </h1>'); 
    	  	if(err) { throw err; } // check if connection is ok, else err-output
    
    	  	db.collection("weatherCOLL").findOne(function(err, output) {  // finds the first object/temperature
    	    res.write('Hello World! <br><hr> The weather is '+ output.temperature +' today'); 
    		res.end();
    		db.close(); // close the Database connection
    	  	});
        });
    });
    
    var port = process.env.PORT || 3000; // either use the port 3000 or a port which is in the "environment variable" - the cloud will deliver us such a port 
    app.listen(port); // tell nodejs to listen to this port and give response
    
    console.log('I am ready and listening on %d', port); // write something nice in the console, that the Developer sees, it works

    In this code snippet, the basic idea is that you connect to the database which was just created and print an output of the WeatherCOLL which is simply a collection we created and added the temperature=cold. So let’s try it out. Navigate to the folder where your app is placed and run the know command to start a local Node.js app:

    node app.js
    

    If this worked successfully, you will be able to see the following text when you access http://localhost:3000 on your browser.

    step04

  3. Input and GET’s
    Okay, that was easy! Now let us add a small button to change the weather. We will be adding a new “app.get” section and enhance our existing output by making use of a small form:

    [...]
    
    /*
     * Gather  all requests from / 
     */
    app.get('/', function (req, res) { // telling nodeJs to get all commands from / into this function
        /* Connect to MongoDB */  	
    	mongoClient.connect( "mongodb://localhost:27017/weatherDB" , function(err, db) { // connect to the local Database
    		res.writeHead(200,{"Content-Type" : "text/html"}); // write header
    
    	  	res.write('<h1>How is the weather ? </h1>');
    	  	if(err) { throw err; } // check if connection is ok, else output
    
    	  	db.collection("weatherCOLL").findOne(function(err, output) {  // finds the first object/temperature
    	    	res.write('Hello World! <br><hr> The weather is '+ output.temperature +' today'); 
    		  	res.write('<br><hr><form action=\'/temp\'><h3>Change weather</h3><br><input type=text name=temp value=hot><br><input type=submit value=\'Change the weather...\'></form>'); // add a simple inputfield
    			res.end();
    			db.close(); // close the Database connection
    	  	});
        });
    });
    
    /*
     * Gather all requests from /temp 
     */
    app.get('/temp', function (req, res) { // telling nodeJs to get all commands from /temp into this function
     
     	/* Connect to MongoDB */
    	mongoClient.connect( "mongodb://localhost:27017/weatherDB" , function(err, db) { // connect to the local database
    	  	if(err) { return console.dir(err); } // check if connection is ok, else output
    
    	  	db.collection('weatherCOLL').drop(); // drop the collection if existing
      		db.collection('weatherCOLL').insert( {"temperature": req.query.temp } ) // add a new object with "temperature"
    		res.send("done <hr> <a href=\'/\'>back</a>");
    		res.end();
      		db.close(); // close the Database connection
      	});
    });
    
    [...]

    Test it out by restarting your App with the command “node app.js”. Important: you just created a security-bug, by allowing “every input” to be directly written into the database. This is a hello world App, but please be aware of the threat we have just created by simply adding some easy html code into the “temperature” field you can easily cause serious damage. Therefore, check for modules such as validator to prevent being vulnerable to XSS Hijacks.

    In summary, you just created a simple and easy hello-world App writing into a database.

 

Move into the Cloud

This was straight forward so far. You have a local App with a local database running hence what is the need to move into the Cloud?
Well, we are not offering a sales-pitch here, however, as simple as it sounds – when operating the database, one has to always be sure and ensure that you have an environment running and that you able to deploy the newest Node.js engine on your middleware and so forth. This is no easy task, in fact, it is actually a big task in the entire value-chain of providing a digital service.

So let’s figure out, how we go onto the Cloud.

  1. Prepare the Cloud, provision a Service
    As a first step, let us prepare our Cloud environment. If you are working with a CloudFoundry provider such as Swisscom, Pivotal, IBM or others, you can easily provision your Services in the same way with a standardized command line or the corresponding API. This is a real difference of an open-standard PaaS environment; whereas if you are using AWS, Google and others, you will face the issue of other provisioning and lifecycle mechanism on each instance. That’s what we refer to as “lock-in” 🙂 .Okay, so let us go with CloudFoundry for the moment:
    Start your CLI and check the available services of your CloudFoundry provider with the command “cf m”. (Note: check the chapter “CloudFoundry CLI” within our first blog, if you do not have the CF-CLI yet)step05
    Following this, create the service that you require. In our case, a small MongoDB:

    cf create-service mongodb small weatherDB

    This now creates your own MongoDB-Service which is ready to be used within seconds after creation – operation and lifecycle is provided by the Cloud provider. You can add new features on your App, rather than ensuring that the database works. Further details on how you can manage your services with the CLI can be found in our documentation.

  2. Service-configuration and Push your App
    Now we will push our new App into the Cloud. From the onset, we have to notify our App where it has to connect. Therefore, we make small changes in our connect function and ensure that we do not connect to our local database, but instead to the Cloud Database:

    [...]
    
    var vcap_services = JSON.parse(process.env.VCAP_SERVICES); // Get Environment variables from your App ; more at https://docs.developer.swisscom.com/apps/deploy-apps/environment-variable.html
    var uri = vcap_services.mongodb[0].credentials.uri; // Get the URI with the credentials
    
    /*
     * Gather  all requests from / 
     */
    app.get('/', function (req, res) { // telling nodeJs to get all commands from / into this function
        /* Connect to MongoDB */  	
    	mongoClient.connect( uri , function(err, db) { // connect to the local database
    		res.writeHead(200,{"Content-Type" : "text/html"}); // write header
    
    
    [...]
    
    
    /*
     * Gather all requests from /temp 
     */
    app.get('/temp', function (req, res) { // telling nodeJs to get all commands from /temp into this function
     
     	/* Connect to MongoDB */
    	mongoClient.connect( uri , function(err, db) { // connect to the local database
    	  	if(err) { return console.dir(err); } // check if connection is ok, else output

    Now we are ready to push our App the next time. Go into the folder of your Node.js App and execute the command:

    cf push myApp123 --no-start

    With the “–nostart” param we ensure, that the app will be deployed but doesn’t start yet. That way we save some time in binding it.
    Further details on service-configurations in Node.js can be found in our documentation.

  3. Bind your Service
    We created a MongoDB-Service (you can view it with the command “cf services”) and we pushed the App into the Cloud. However, we did not connect both – if you attempt to access your App now, you will receive an “Internal Server Error”.So let’s do exactly that:

    cf bind-service myApp123 weatherDB

    This directly connects the App with the database. As a result, all required connection-parameters are now available in the environment variable of the App. After the binding, we need to shortly “restage” the App – a necessary step to make the environment-variables active and visible for the App:

    cf restart myApp123

    Generally, it is also possible to see, as well as actually provision all these steps with a UI/Portal, in our case, within the Developer Console;

  4. Initialize a Temperature
    As our Database is still empty, we’ve to “initialize” it. You can easily do that by visiting your app and directly submit a firt entry :
    http://myapp123.scapp.io/temp?temp=cold
  5. Start changing the weather
    Now, you should be able to access your App (under your URL, for instance http://myapp123.scapp.io/) and define the Temperature entry in your fresh-MongoDB!

This series of blogs show a simple step-by-step guide for going onto the Cloud and learn about the workings of Cloud-native Apps. To make full and optimum use of your MongoDB, also refer to our guide on connecting to the MongoDB from your local laptop as this would even avoid the requirement to install a MongoDB locally.

 

More about Cloud Services
Learn more about the Service offering of Swisscom on our feature page and in the documentation and obviously the pricing. Similar offerings can be found by other Cloud Foundry providers where you can provision your Node.js App with MongoDB the same way. A list of the current providers can be found at the official CloudFoundry-Provider listing.

 

More about Node.js
cat

A quite interesting book we can recommend is the “Web Development with Node and Express” by Ethan Brown. “Learn how to build dynamic web applications with Express, a key component of the Node/JavaScript development stack. In this hands-on guide, author Ethan Brown teaches you the fundamentals through the development of a fictional application that exposes a public website and a RESTful API. You’ll also learn web architecture best..”