Enterprise Mobile Architecture to start with… | Home | Trishanku

Dec 14, 2011

Mobile Architecture using jQuery, Node.js (+ express) and CouchDB

Apache Couchdb is the chosen one and now we have a complete (sort of) lightweight architecture for mobile apps. For those who think that the first line was an abrupt one, please refer to the previous post.

I now have a working example (a shoddy one) of a web app for entering fantastic details of the fauna you might be a keen observer of. The web app works but is without any validation, without any error handling and bloody hell - without even a feedback. So what the hell is a working app?

  1. Does this look good on a mobile? Does it actually look like it was built for mobile?
  2. Is it lightweight? (Define lightweight)
  3. Is it easy to develop? What are the skillsets required?
  4. Is it scalable? (Think reverse of what you just thought i.e. extremely small to start with not whether it can cater to your prospective 2.5million users after 2 years. Maybe that too.)
  5. Is it secure?

For question 1, I picked up the popular jQuery Mobile Framework after reading a couple of comparisons. It is very easy to use and the online documentation is very well organised and detailed. And the primary reason, it looks great on both iOS and Android. You can actually see a silly web app called Numbers, to help your kid fall asleep while counting sheep. It just uses a couple of jQuery Mobile elements.

The second question is the most difficult one and depends on how lightweight is defined. For some, it could mean less CPU intensive, less disk space or uncomplicated licensing model. For others, it could mean easy to setup, easy to configure and easy to debug. I am no authority on this, but Node.js seems to give a positive reply to many of these. And so does CouchDB. There are other NoSQL options - MongoDB, being a very popular choice. But what impressed me about CouchDB was the fantastic RESTful design it has implemented. And how does it matter? Well, inquiring and manipulating data through a middleware using simple HTTP GET, PUT, DELETE calls gets amazingly simple, while handling the HTTP requests from the front-end, without any extra learning curve.

Question 3 is the easiest to answer - we don’t need anything other than HTML/Javascript. How much easier can it get?

Both Node.js and CouchDB are being touted as the ultimate in scalability and performance. But as I said, let’s see those from the current situation rather than the future. When you are starting with the business idea and expect the volumes to pick up only after a certain period or if you just want to test the waters, do you have to invest heavily upfront in an unpredictable business model? And does it offer the flexibility to change rather than build to last? Solutions such as Node.js and NoSQL are good answers to this predicament. Q4 answered.

These are still very early days to say much about Node.js security. So no idea yet. But we can at least rule out SQL injection :-)

Anyway, too much rambling above. Here is the action (Linux or Mac) -

1. Simple 'untar Node.js source, ./configure, make, sudo make install' routine in Linux/Mac OS X. No major dependency issues other than Python and OpenSSL. (test using 'node -v')

2. Install npm - Node Package Manager using the one line install. It didn’t work due to proxy settings as I was trying with superuser credentials and environment variables exported in normal login are available only by using the -E option. Also, I had to replace sh with bash. Eventually, 'curl npmjs.org/install.h | sudo -E bash' worked. (test using 'npm -v')

3. 'npm install express' - for the Node.js module, express - a web framework on node, which will be our middleware.

4. Installing CouchDB on Mac was easy using Homebrew - 'brew install couchdb'. But on Ubuntu, building with source was a safe bet. There are quite a few dependencies to be handled on Ubuntu. (test using 'couchdb' or 'sudo couchdb')

The above are just hints, search on the net and ample of instructions (detailed) can be found.

Though I went through a few trials and errors, the following is how to make it work.

1. After starting CouchDB, create your database from the command line 'curl -X PUT http://127.0.0.1:5984/acme_fauna' or accessing http://localhost:5984/_utils/ through a browser and selecting the appropriate options.

2. Create the index.html (in a folder called ‘public’) which will be your data entry screen with the jQuery Mobile niceties in.

<!DOCTYPE html>
<html>
<head>
  <title>ACME Fauna Entry</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="jquery.mobile-1.0.min.css" />
  <script type="text/javascript" src="jquery-1.6.4.min.js"></script>
  <script type="text/javascript" src="jquery.mobile-1.0.min.js"></script>
  <script language="JavaScript" type="text/javascript">
  </script>
</head>
<body> 

<div data-role="page" data-theme="b" data-content-theme="b">

  <div data-role="header">
    <h1>ACME Fauna Entry</h1>
  </div><!-- /header -->

  <div data-role="content">
    <form action="http://localhost:3000/fauna" method="post">
      <fieldset>
        <div data-role="fieldcontain" class="ui-hide-label">
          <label for="type" class="select">Type</label>
          <select name="type" id="type">
            <option value="bird">Bird</option>
            <option value="moth">Moth</option>
            <option value="mammal">Mammal</option>
            <option value="reptile">Reptile</option>
          </select>
          <label for="cname">Common Name</label>
          <input type="text" name="cname" id="cname" value="" placeholder="Common Name"></input>
          <label for="sname">Scientific Name</label>
          <input type="text" name="sname" id="sname" value="" placeholder="Scientific Name"></input>
          <label for="subtype">Subtype</label>
          <input type="text" name="subtype" id="subtype" value="" placeholder="Subtype"></input>
          <label for="Description">Description</label>
          <textarea name="desc" id="desc" value="" placeholder="Description"></textarea>
          <input type="submit" id="submit" value="Submit"></input>
          <input type="reset" id="cancel" value="Cancel"></input>
        </div>
      </fieldset>
    </form>
  </div><!-- /content -->

  <div data-role="footer">
    <div data-role="navbar">
      <ul>
      <li><a href="#" style="text-align:center" onclick="List()">List</a></li>
      <li><a href="#" style="text-align:center" onclick="Review()">Review</a></li>
      </ul>
    </div><!-- /navbar -->
  </div><!-- /footer -->

</div><!-- /page -->

</body>
</html>

3. The form in index.html will be submitted through a POST method to a web server (webserver.js) that will be implemented using express on Node.js

var http = require('http');
var express = require('express');

var getcuuid = {
  host: 'localhost',
  port: 5984,
  path: '/_uuids',
  method: 'GET'
};

var createcdoc = {
  host: 'localhost',
  port: 5984,
  path: '',
  method: 'PUT'
};

var app = express.createServer();
app.use(express.bodyParser());
app.use(express.static('public'));
//app.use(express.static(__dirname + '/public'));

app.get('/', function(req, res){
  res.send('Hello World');
});

app.post('/fauna', function(req, res){
  // GET http://localhost:5984/_uuids to get a new UUID for each entry
  var cuuid = '';
  var cureq = http.request(getcuuid, function(cures) {
    cures.setEncoding('utf8');
    cures.on('data', function(cuuiddata) {
      cuuid = JSON.parse(cuuiddata).uuids[0];
      //console.log(cuuid);

      // PUT http://localhost:5984/acme_fauna/<UUID> with data in JSON form i.e. req.body
      createcdoc.path = '/acme_fauna/'+cuuid;
      //console.log(createcdoc.path);
      var ccreq = http.request(createcdoc, function(ccres) {
        ccres.on('data', function(ccdata) {
        //console.log(ccdata);
        });
      });
      //console.log(JSON.stringify(req.body));
      ccreq.write(JSON.stringify(req.body), encoding='utf8');
      ccreq.end();
    });
  });
  cureq.end();
  //res.send(req.body);
  res.redirect('home');
});

app.listen(3000);

4. Run the webserver using 'node <path/to>webserver.js'. This should be run from the folder containing the folder ‘public’ and providing the correct path of webserver.js to the node command.

5. Access the web app through any browser by pointing to http://localhost:3000/

6. Add birds, mammals, moths and insects in the database to your heart’s content.

The diagram is still pending!

Comments are closed.