Recent Posts

  • Migrating to Jekyll

    So finally, I bit the bullet. I have been thinking of migrating my blog to Jekyll for almost 2 years now, never had a true reason. Well now I do, I am free and bored of the themes that Wordpress offers for free. I have been a long time fan of Wordpress, which I believe is still awesome, but I needed more control on how my blog looks and so I moved.

    Migrating itself was not super hard. There is sufficient help available online, but a quick summary:

    1. Get started with [https://help.github.com/articles/using-jekyll-with-pages/]
    2. Skip the hello world goodie, create a site instead

      bundle exec jekyll new
      bundle exec jekyll build
      bundle exec jekyll serve
      
    3. Migrate your blogs using ExitWp

    4. Migrate comments using Disqus. Read this blog. Use the domain migration tool on Disqus to change the links in the imported comments and get the links right. I basically just did a find and replace in Wordpress exported XML.

    5. Modify the SCSS to make your blog look the way you want.

    6. Attach Google Analytics to your pages if you like stats.

    7. Get yourself a coffee :-)

    There are three additional benefits of this:

    1. The best thing about a Jekyll backed blog is that there is no database involved. It is static content and is super fast in rendering!
    2. It is hosted for free on github.
    3. And you get to write your blogs in markdown!

  • Building a web app with node js

    NodeJS is an event driven javascript framework that makes writing asynchronous code a piece of cake! For small apps and a limited user base, this is almost magical - the code can be churned out fast, it is clean and it is perfectly unit testable. The purpose of this blog is not to sell node js though, we'll instead look at how an application could be built easily.

    The applications I work on are primarily client-server, like web apps, or mobile apps with a backend. So here's what my toolkit with node js looks like:

    • Express JS: Sinatra like web framework that gives basic structure to the web app

    • Sequelize JS: ORM framework

    • Require JS: for modularization

    • Node DB Migrate module: just like rails db migrations

    • Mocha JS: For unit tests

    • Chai JS: For test assertions

    • Crypto: For encryptions

    • Angular JS: For the front end

    • MySQL: database

    Lets keep the front end out of scope for this article and only focus on getting an app that can serve JSON over REST.

    Setting up the environment

    1. Install nodejs
    2. Next, we need expressjs
    3. Run the following

          npm install -g express
          # create the app now. we'll call it 'myapp'
          express myapp
          cd myapp
          node app.js
      
    4. You should now see something like this "Express server listening on port 3000"

    5. Yay! You now have a basic Express JS app running!

    Configuring the app

    1. The ExpressJS guide is a pretty good resource for getting started, so I would recommend that you read through it.

    2. Next, add the following in package.json under dependencies:

          "mysql": "*",
          "supervisor": "*",
          "db-migrate": "*",
          "sequelize": "*",
          "requireindex": "*",
          "mocha": "*",
          "crypto": "*",
          "chai": "*"
      
    3. Save package.json and run "npm install"

    4. Supervisor module is a great module for development environments and it auto reloads the app on change, so you dont have to restart your node server every time. To run the app using supervisor, just use "supervisor app.js"

    5. Requireindex is a nice module that helps get all objects from  a directory into a single object, without adding a "require" for each file

    6. Add the error handler in app.js (as described in expressjs guide)

      app.use(function(err, req, res, next){
        console.error(err.stack);
        res.send(500, 'Something broke!');
      });
      
    7. Run the app again and access using http://localhost:3000.

    Adding database support

    1. Install mysql

    2. We already have the node module included in package.json (mysql), so the app is now ready to start talking to the database

    3. We'll use node db migrate module to set up the database.

    4. Create a file database.json under myapp. The contents should look as follows:

      {
        "dev": {
          "driver": "mysql",
          "user": "root",
          "database": "myapp"
        },
      
        "test": {
          "driver": "mysql",
          "user": "root",
          "database": "myapp_test"
        },
      
        "production": {
          "driver": "mysql",
          "user": "root",
          "database": "myapp"
        }
      }
      
    5. Create a db.js in the myapp directory with the following contents:

      var express = require('express'),
          Sequelize = require("sequelize");
      
      var app = express();
      var env = app.get('env') == 'development' ? 'dev' : app.get('env');
      
      // db config
      var fs = require('fs');
      var dbConfigFile = __dirname + '/database.json';
      var data = fs.readFileSync(dbConfigFile, 'utf8');
      
      var dbConfig = JSON.parse(data)[env];
      var password = dbConfig.password ? dbConfig.password : null;
      var sequelize = new Sequelize(dbConfig.database, dbConfig.user, password, { logging: true });
      
      exports.sequelize = sequelize
      
    6. The above uses the same file (database.json) as used by db-migrate module so all your configuration stays at one place. It also initializes our ORM framework viz. sequelizejs.

    7. To use this, just add require('db.js') as required and get sequelize.

    Configure unit tests

    1. Modify your package.json and add the following under "scripts":

      "pretest": "db-migrate up -m ./migrations --config ./database.json -e test",
      "test": "NODE_ENV=test mocha test test/*/**"
      
    2. The above will ensure that your db migrations are run automatically when you run the tests, and also that you don't have to remember longish commands for recursively running tests in sub directories.

    3. Add a basic test case under "test" directory.

      var expect = require('chai').expect,
      should = require('chai').should();
      var db = require("../db.js").sequelize;
      var DataTypes = require("sequelize");
      var assert = require("assert")
      describe('DB', function(){
          it('should check db connection', function(done){
              db
              .query("select count(1) from users")
              .success(function(o){
                  expect(o.length).to.not.equal(0);
                  done();
              }).error(function(error) {
                  done();
              });
        })
      })
      
    4. Prepare for test data - create a file _setup.js under tests and put the following:

      var db = require('../db.js').sequelize;
      
      var testData = [
      "INSERT INTO users (name) VALUES ('test user');",
      "INSERT INTO users (name) VALUES ('test user 2');"
      ];
      
      // now run the test data
      testData.forEach(function(sql){
          db.query(sql).success(function(){ }).error(function(e){ console.log(e); });
      });
      
      console.log(">>>> starting tests...");
      
    5. The SQLs above are obviously just indicative and you'll have to add your SQLs as needed.

    6. Run npm test to execute the tests!

    Build a model

    1. Start creating your db migrations (like db-migrate create users) ! They will be stored under myapp/migrations directory.

    2. Run the following:

      db-migrate create users
      
    3. Now open the migration that has been created under migrations directory and add table definition, e.g.

      var dbm = require('db-migrate');
      var type = dbm.dataType;
      
      exports.up = function(db, callback) {
          db.createTable('users', {
              id: { type: 'int', primaryKey: true, autoIncrement: true },
              name: 'string'
            }, callback);
      };
      
      exports.down = function(db, callback) {
          db.dropTable('users', callback);
      };
      
    4. Run the migrations to create users table.

    5. Now create a directory called "models" under myapp. This is where we'll put our models.

    6. Under models, create users.js with the following contents (or similar)

      var db = require("../db.js").sequelize;
      var crypto = require('crypto');
      var DataTypes = require("sequelize");
      
      var User = function(name, username, password) {
       this.name = name,
       this.user_name = username,
       this.password = password
      };
      
      var users_table = db.define('users', {
            name: DataTypes.STRING,
            user_name: DataTypes.STRING,
            password: DataTypes.STRING
          }, {
            timestamps: false,
            underscored: true
          });
      
      User.prototype.save=function(onSuccess, onError) {
          var shasum = crypto.createHash('sha1');
          shasum.update(this.password);
          this.password = shasum.digest('hex');
      
          users_table.build(this).save().success(onSuccess).error(onError);
      };
      
      User.find=function(username, password, onSuccess, onError) {
          users_table.find({ where: {user_name: username, password: password}, attributes: ['id', 'name', 'user_name'] }).success(onSuccess).error(onError);
      };
      
      User.lookup=function(name, onSuccess, onError) {
          users_table.findAll( { where : [ "name like ?", '%' + name + '%' ] } ).success(onSuccess).error(onError);
      };
      
      exports.get=User;
      exports.table=users_table;
      
    7. As a reminder, we use sequelizejs for ORM and crypto for encryptions above.

    8. To use this model, all we now need is to create an object of User and call user.save(), or directly call User.find or User.lookup as needed. Notice that these take callbacks for success and error, thats because node js is a totally event driven framework and everything is synchronous. These methods don't return anything :smile:

    9. Lets add a route, create user.js under routes directory.

      var User = require('../models/users').get;
      
      exports.authenticate = function(req, res) {
        User.find(req.body.username, req.body.password, function(o) {
          if (o) {
            res.json(o.selectedValues);
          } else {
            res.send(401, "Auth failed");
          }
        }, function(error) {
          console.log(error);
          res.send("Auth failed");
        });
      };
      
    10. And in app.js, add the route

      app.post('/authenticate', user.authenticate);
      
    11. All done! You now have an app that can connect to the database and authenticate users!

    In the next blog, we'll see how we can quickly assemble a front end

  • Don't write off Microsoft just yet!

    I just bought a new laptop with the cool new Windows 8 installed. I must admit that I was a bit skeptical of how the new OS would be, but its totally taken me by surprise, and in a good way! 

    First, I absolutely adore the new Metro layout. Its like a cool dashboard where I have all my tools and information handy for me to get started. From facebook to gmail to google search, everything is a shortcut on there. And its not just a shortcut! The mails tile shows new ones and facebook one shows the highlights - everything that makes you decide if you want to click that icon or not. Similarly, there are news feeds, weather updates and other handy info. Its really much more useful than the mostly empty windows desktop that exists on previous versions. And its much brighter and colorful too!

    Secondly, IE 10 is a total pleasure to use. Its super fast, and feels much lighter. I also hear that it finally adheres to global standards too (yay, developers rejoice) !

    Thirdly, each new window/ app is a full screen by default. No task bar, no title bar, nothing. It makes the full use of the screen - can it get better ?!

    Oh well, some things require 2 clicks (including a right click) that should really just need one. Like closing windows. Yeah. You either drag a window to the bottom to ask it to go to hell (or where ever), or you right click, find yourself a cross button and close the damn thing. I wish there was a close button that would appear when I hover around one of the corners, closing a window should be a one click thing.

    And I could not install Google Chrome on Win 8 - its just kept on hanging up on me.

    I think the performance of the OS and system in general is pretty good, and the fact that the same system will run on mobile and desktop/ laptop computers is pretty encouraging. May be we should consider how we'll develop apps for windows along with Android and iOS ? ha ha! I hear Windows 8 is all HTML and JS anyways!

Older Posts

subscribe via RSS