Wednesday, December 14, 2011

Switching the Backbone.js Backend to Node-Dirty

‹prev | My Chain | next›

I am going to wind down my exploration of Backbone.js by making my sample app, Funky Backbone.js Calendar a little easier to setup.

I would like folks to be able to get up and running with two steps: git clone and then a node.js npm install. To get npm install to work without any other arguments, I need the package.json file to include the up-to-date dependencies:
{
    "name": "funky-funky-calendar"
  , "version": "0.0.1"
  , "private": true
  , "dependencies": {
      "express": "2.5.2"
    , "jade": ">= 0.0.1"
  }
}
To try that out, I wipe my node_modules directory, recreate it, and then run npm install:
➜  calendar git:(master) ✗ npm install
jade@0.19.0 ./node_modules/jade
├── mkdirp@0.2.1
└── commander@0.2.1
express@2.5.2 ./node_modules/express
├── qs@0.4.0
├── mime@1.2.4
├── mkdirp@0.0.7
└── connect@1.8.2
With that, I can start my app the usual node way:
➜  calendar git:(master) ✗ node app
Express server listening on port 3000 in development mode
And verify that the application still starts:


Cool beans.

Next up, I would like to remove the dependency on CouchDB, since CouchDB is dying (I kid!). Actually, I would like to remove it to eliminate a dependency. Ideally the data store would be built directly into the application. There are a number of solutions for doing just that in the node universe. I am partial to node-dirty, if only because I have used it before.

So I add that to the list of my application's dependencies:
{
    "name": "funky-funky-calendar"
  , "version": "0.0.1"
  , "private": true
  , "dependencies": {
      "express": "2.5.2"
    , "jade": ">= 0.0.1"
    , "dirty": "0.9.5"
  }
}
And update my installed packages:
➜  calendar git:(dirty) ✗ npm install
dirty@0.9.5 ./node_modules/dirty 
➜  calendar git:(dirty) ✗ npm ls
funky-funky-calendar@0.0.1 /home/cstrom/repos/calendar
├── dirty@0.9.5 
├─┬ express@2.5.2 
│ ├─┬ connect@1.8.2 
│ │ └── formidable@1.0.8 
│ ├── mime@1.2.4 
│ ├── mkdirp@0.0.7 
│ └── qs@0.4.0 
└─┬ jade@0.19.0 
  ├── commander@0.2.1 
  └── mkdirp@0.2.1 
At this point, it is just a matter of working through the various GETs and POSTs and PUTs in my express backend:
app.get('/', function(req, res){ /* ... */ });
app.get('/appointments', function(req, res){ /* ... */ });
app.delete('/appointments/:id', function(req, res){ /* ... */ });
app.put('/appointments/:id', function(req, res){ /* ... */ });
app.post('/appointments', function(req, res){ /* ... */ });
For each of those, I need to replace CouchDB operations with the node-dirty equivalent.

For example, the GET of the /appontments resource would need to change from:
app.get('/appointments', function(req, res){
  var options = {
    host: 'localhost',
    port: 5984,
    path: '/calendar/_design/appointments/_view/by_month?key="'+ req.param('date') +'"'
  };

  http.get(options, function(couch_response) {
    console.log("Got response: %s %s:%d%s", couch_response.statusCode, options.host, options.port, options.path);

    couch_response.pipe(res);
  }).on('error', function(e) {
    console.log("Got error: " + e.message);
  });
});
To be replaced with:
app.get('/appointments', function(req, res){
  console.log("[get /appointments]");

  var list = [];
  db.forEach(function(id, appointment) {
    if (appointment) list.push(appointment);
  });

  res.send(JSON.stringify(list));
});
In there, I do a blocking forEach over all DB records (high performance, this is not) to build up the list of all appointments. Then I simply "stringify" the resultant JSON to be sent back to the Backbone code.

I also have to simplify some of the Backbone code. It not longer needs to handle CouchDB structures. Since I am sending back pure lists, the default parsing scheme in Backbone works just fine.

After working through each HTTP verb in turn, I have my Funky Calendar working against node-dirty:


I can create, update, delete and get records. It just works!

That is a lovely stopping point for tonight. I will update the instructions in the README tomorrow. For now, if you would like to try this out, this should work:
git clone git://github.com/eee-c/Funky-Backbone.js-Calendar.git
cd Funky-Backbone.js-Calendar
git co dirty # still in a branch for now
npm install
node app
The above assumes that you have node.js 0.6+ installed.


Day #235

No comments:

Post a Comment