Thursday, May 23, 2013

Developing with Derby JS - Installation


In this series, I will try to show how to build a step by step web application. My ultimate goal will be to write an app that could gather user statistics from Facebook, similar to Wolfram Alpha Facebook Report.
The first step in the series is installation:
There are several ways to install NodeJs. For Ubuntu, the easiest way is to install through apt-get
sudo apt-get install node
Although this is convenient, I try not to go with the apt-get route because they tend to be outdated. For me, opensource means living on the edge with latest release, sometimes with alpha software.
Here are the steps you will need to follow to install node js. Note that we are installing nodeJS locally. I tried to install with sudo, then there were permission issues which led me to do it this way.
wget http://nodejs.org/dist/v0.10.12/node-v0.10.12-linux-x64.tar.gz
tar -xvf node-v0.10.12-linux-x64.tar.gz
cd node-v0.10.12-linux-x64
./configure --prefix=/home/alias/Applications/node/
make install
echo 'export PATH=$PATH:/home/alias/Applications/node/bin' >> ~/.bashrc
Now that you are done with installing this node, next on our stack is to install Redis
wget http://redis.googlecode.com/files/redis-2.6.14.tar.gz
tar -xvf redis-2.6.14.tar.gz
make -j 6
make test
make PREFIX=/home/alias/Applications/redis/ install
echo 'export PATH=$PATH:/home/alias/Applications/redis/bin' >> ~/.bashrc
cd utils 
./install_server
This will ask a bunch of questions. Defaults are usually fine unless you are not comfortable with it. At the last step, it will ask for redis executable location, and you are going to respond with
/home/alias/Applications/redis/bin/redis-server
Next step and the final step is to install MongoDB: For this, I used bare apt-get
sudo apt-get install mongodb-server
If all is well, you should be good to go.
For now, let's start the servers and let's not do this using services, but use console instead (except for mongo):
/home/alias/Applications/redis/bin/redis-server 
sudo /etc/init.d/mongodb restart
Now that we are good to go, we are ready to prepare the initial dummy web app. To do that, we first need to install derby through node package manager (NPM) which is a repository of projects just like apt-get is, except it's more frequently updated.
npm install -g derby
The -g implies that the module should be installed globally. Now that we specified node folder to be "/home/alias/Applications/node", the installed module has gone into "/home/alias/Applications/nod/lib/node_modules". It's time to invoke our project generator
derby new SocialReport
Now note that the project is installed together with its dependencies which are found in the node_modules folder.
If we go into SocialReport and type
npm start
we are going to end up with the following bootstrap template (haters gonna hate).
Bootstrap twitter template
It's all well.
Derby uses MVC paradigm which creates a clear layer between model, controller and the view. It's a realtime framework, making it easier to build scalable realtime websites so that users can interact with the site, see data changes are reflected immediately and so on. Being a NodeJS tool, you don't have to write your backend code and front end code in different languages which makes "Context Switch" really easy. Since it's javascript (read: single thread), it clears you from having to think about concurrency issues. Using its event queue, it enables you to quickly write scalable code (well, to an extent - probably more on that later).
Let's now look at the folder structure.
lib
styles
ui
views
package.json
server.js
  • package.json: This is the manifest for the project. You can put information about project, as well as dependencies and initialization scripts. A sample is as follows:
    { "name": "web", "description": "", "version": "0.0.0", "repository": { "type": "git", "url": "" }, "scripts": { "start": "node server.js" }, "dependencies": { "connect-mongo": "~0.3.2", "derby": "0.5.x", "derby-auth": "git://github.com/lefnire/derby-auth.git#0.5", } "engines": { "node": "0.10.x" }, }
Note that the format is unsurprisingly JSON - no more eye hurting XML. I tried to give examples of multiple use cases for dependencies. If you specify your dependency like connect-mongo or derby, it will fetch it from the global node repository. If you would like to go with the sourcecode directly and like to live dangerously, 3rd row is your friend. If you want to lock your project to a specific version of a specific packet, you should specify the version number, otherwise you can pass "", my personal opinion is that locking to a specific version ensures that it's going to work in the future. Otherwise, if you think new stuff is always the best, go with "", and occasionally deal with breakages - which is mostly fine. In the same file, you provide the node version to make sure it's working against the right version.
  • server/index.js
This is the file that does the initialization for mongodb, derbyjs, redis and so on. For each of the components, it's possible to specify multiple configurations depending on if you're in production or not.
The file has several defaults you might need to enable.
  • app/index.js
This is the controller, but interestingly it is named App. In the index.js file, you define the routes (ie what url invokes which action), and also specify the action i.e., what would happen if a request is made.
// Derby routes are rendered on the client and the server
app.get('/', function(page) {
  page.render('home');
});
  • views Views folder have the templates that you use to render actions. DerbyJS use handlebar like templates for it's operations. You can use htmls, and you should also separate your design into sections like
and so on.
What's next?
Passport JS Configuration and Facebook integration is next on our list. It will involve configuring passportJS for authentication using facebook and setting up routes for the authentication logic. Google plus integration will also be shown.
After that we will work on some of the data collection/mongodb aspect using facebook graph queries/fql.

Wednesday, April 10, 2013

v0.3.15 - Node.js MVC: Express.js + Derby.js Hello World Tutorial

DerbyJS — Node.js MVC Framework

Express.js is a popular node frameworks which uses middleware concept to enhance functionality of applications. Derby is a new sophisticated Model View Controller (MVC) framework which is designed to be used with Express as it’s middleware. Derby also comes with the support ofRacer, data synchronization engine, and Handlebars-like template engine among many other features.

Derby.js Installation

Let’s set up a basic Derby application architecture without the use of scaffolding. Usually project generators are confusing when people just start to learn a new comprehensive framework. This is a bare minimum “Hello World” application tutorial that still illustrates Derby skeleton and demonstrates live-templates with websockets.
Of course we’ll need Node.js and NPM which can be obtained atnodejs.org. To install derby globally run:
$ npm install -g derby
To check the installation:
$ derby -V
My version as of April 2013 is 0.3.15. We should be good to go to creating our first app!

File Structure in a Derby.js App

This is the project folder structure:
project/
  -package.json
  -index.js
  -derby-app.js
  views/
    derby-app.html
  styles/
    derby-app.less

Dependencies for The Derby.js Project

Let’s include dependencies and other basic information in package.jsonfile:
 {
  "name": "DerbyTutorial",
  "description": "",
  "version": "0.0.0",
  "main": "./server.js",
  "dependencies": {
    "derby": "*",
    "express": "3.x"
  },
  "private": true
}
Now we can run npm install which will download our dependencies intonode_modules folder.

Views in Derby.js

Views must be in views folder and they must be either in index.htmlunder a folder which has the same name as your derby app JavaScript file, i.e., views/derby-app/index.html, or be inside of a file which has the same name as your derby app JS file, i.e., derby-app.html.
In this example “Hello World” app we’ll use <Body:> template and{message} variable. Derby uses mustach-handlebars-like syntax for reactive binding. index.html looks like this:
<Body:>
  <input value="{message}"><h1>{message}</h1>
Same thing with Stylus/LESS files, in our example index.css has just one line:
h1 {
  color: blue;
}
To find out more about those wonderful CSS preprocessors check out documentation at Stylus and LESS.

Building The Main Derby.js Server

index.js is our main server file, and we begin it with an inclusion of dependencies with require() function:
var http = require('http'),
  express = require('express'),
  derby = require('derby'),
  derbyApp = require('./derby-app');
Last line is our derby application file derby-app.js.
Now we’re creating Express.js application (v3.x has significant differences between 2.x) and an HTTP server:
var expressApp = new express(),
  server = http.createServer(expressApp);
Derby uses Racer data synchronization library which we create like this:
var store = derby.createStore({
  listen: server
});
To fetch some data from back-end to the front-end we instantiate model object:
var model = store.createModel();
Most importantly we need to pass model and routes as middlewares to Express.js app. We need to expose public folder for socket.io to work properly.
expressApp.
  use(store.modelMiddleware()).
  use(express.static(__dirname + '/public')).
  use(derbyApp.router()).
  use(expressApp.router);
Now we can start the server on port 3001 (or any other):
server.listen(3001, function(){
  model.set('message', 'Hello World!');
});
Full code of index.js file:
var http = require('http'),
  express = require('express'),
  derby = require('derby'),
  derbyApp = require('./derby-app');

var expressApp = new express(),
  server = http.createServer(expressApp);

var store = derby.createStore({
  listen: server
});

var model = store.createModel();

expressApp.
  use(store.modelMiddleware()).
  use(express.static(__dirname + '/public')).
  use(derbyApp.router()).
  use(expressApp.router);

server.listen(3001, function(){
  model.set('message', 'Hello World!');
});

Derby.js Application

Finally, Derby app file which contains code for both a front-end and a back-end. Front-end only code is inside of app.ready() callback. To start, let’s require and create an app. Derby uses unusual construction (not the same familiar good old module.exports = app):
var derby = require('derby'),
  app = derby.createApp(module);
To make socket.io magic work we need to subscribe model attribute to its visual representation, in other words bind data and view. We can do it in the root route, and this is how we define it (patter is /, a.k.a. root):
app.get('/', function(page, model, params) {
  model.subscribe('message', function() {
    page.render();  
  })  
});
Full code of derby-app.js file:
var derby = require('derby'),
  app = derby.createApp(module);

app.get('/', function(page, model, params) {
  model.subscribe('message', function() {
    page.render();  
  })  
});  

Launching Hello World App

Now everything should be ready to boot our server. Execute node . ornode index.js and open a browser at http://localhost:3001. You should be able to see something like this: http://cl.ly/image/3J1O0I3n1T46.
Derby + Express.js Hello World App

Passing Values to Back-End in Derby.js

Of course static data is not much, so we can slightly modify our app to make back-end and front-end pieces talks with each other.
In the server file index.js add store.afterDb to listen to set events onmessage attribute:
server.listen(3001, function(){
  model.set('message', 'Hello World!');
  store.afterDb('set','message', function(txn, doc, prevDoc, done){
    console.log(txn)
    done();
  }) 
});
Full code of index.js after modifications:
var http = require('http'),
  express = require('express'),
  derby = require('derby'),
  derbyApp = require('./derby-app');

var expressApp = new express(),
  server = http.createServer(expressApp);

var store = derby.createStore({
  listen: server
});

var model = store.createModel();

expressApp.
  use(store.modelMiddleware()).
  use(express.static(__dirname + '/public')).
  use(derbyApp.router()).
  use(expressApp.router);

server.listen(3001, function(){
  model.set('message', 'Hello World!');
  store.afterDb('set','message', function(txn, doc, prevDoc, done){
    console.log(txn)
    done();
  })   
});
In Derby application file derby-app.js add model.on() to app.ready():
  app.ready(function(model){
     model.on('set', 'message',function(path, object){
     console.log('message has been changed: '+ object);
   })
  });
Full derby-app.js file after modifications:
var derby = require('derby'),
  app = derby.createApp(module);

app.get('/', function(page, model, params) {
  model.subscribe('message', function() {
    page.render();
  })
});

app.ready(function(model) {
  model.on('set', 'message', function(path, object) {
    console.log('message has been changed: ' + object);
  })
});
Now we’ll see logs both in the terminal window and in the browser Developer Tools console. The end result should look like this in the browser: http://cl.ly/image/0p3z1G3M1E2c, and like this in the terminal:http://cl.ly/image/322I1u002n38.
Hello World App: Browser Console Logs
Hello World App: Terminal Console Logs
For more magic in the persistence area, check out Racer’s db property. With it you can set up an automatic synch between views and database!
Let me know if you’re interested in any specific topic for future blog post and don’t forget to checkout my JavaScript books:
The full code of all the files in this Express.js + Derby Hello World app is available as a gist at https://gist.github.com/azat-co/5530311