Camel.js: An Introduction

written in camel.js, javascript, node.js

A routing and integration framework for node.js

Apache Camel

In a previous work project I had the privilege of using Apache Camel for creating an ESB. Camel allows developers to define routing rules using one of the provided domain-specific languages; these include java, spring and blueprint to name a few.

An example of the java dsl can be seen here:

context.addRoutes(new RouteBuilder() {
  public void configure() {
      from("test-jms:queue:test.queue").to("file://test");
  }
});

This copies something from a queue to a file. Notice how little code was needed to do something that would take quite a number of lines if you were to do it yourself.

I’m not going to praise camel any more, I do it enough times a day for people to question my sanity, but theres a famous question on StackOverflow that explains camel much better than I can.

npm

For the past few months I have been writing a lot javascript for various projects and I’ve started to enjoy using node.js for creating server side applications. Coupled with npm (Node Package Manager), it’s been easy to utilise different frameworks to get an application up and running in a very short space of time. We used it heavily for a recent hackathon project.

I’ve always been a fan of package managers and have used maven in most of the java projects I’ve worked on, I have also pretended to use nuget for C# projects as well (#insideJoke). I wanted to create and publish my own npm package that others could use in their projects, and camel.js was an idea I had been thinking about for a while.

Camel.js

My initial plan is to create a ‘camel-like’ javascript framework that allows people to easily define routes between different endpoints.

My definition of ‘camel-like’ is a similar DSL to Apache Camel, but using the strengths of node.js, enabling non blocking asynchronous routes. That not only route between built in node modules like fs, but also integrate with popular npm packages like express.

As of writing this post the current version of camel.js is 0.1.10 and can be installed from npm by running the command:

npm install camel.js

The stats on the npm site say that there have been 320 downloads in the past month! But I have my suspicions that most of these are mirrors/bots, as there have been no issues raised yet on github from anyone using the framework!

NPM

The current functionality is obviously very limited at this early stage, I have added support for reading and writing to files and have packaged it all up as an npm module.

If you wanted to create a simple file transfer application you first need to require the camel.js module, and create a camel context:

var camel = require('camel.js');
var context = new camel.context();

You can then define your route and add it to the context:

route = new camel.route();

route.from('file://source.txt')
     .to('file://result.txt');

context.addRoute(route);

Then start the context, which will process all routes that have been added.

context.start();

You can define as many routes as you like and because we are using the asynchronous callbacks in our file read/write code, the routes themselves will also be processed asynchronously. You can also have as many endpoints defined in a single route as well like so:

route.from('file://source.txt')
     .to('file://result1.txt');
     .to('file://result2.txt');
     .to('file://result3.txt');
     .to('file://result4.txt');
     .to('file://result5.txt');

This would copy the content of source.txt to all the result*.txt files.

Another feature that has just been added in the latest release is reading all the files from a directory, this can be done like so:

route.from('file://sourceDirectory')
     .to('file://result.txt');

Although the code above is pretty pointless as it would overwrite the content of each file in sourceDirectory to result.txt. It will make more sense once I have directory support added to the to function and we can do this:

route.from('file://sourceDirectory')
     .to('file://resultDirectory');

Testing

Once I had my prototype finished, I decided to focus on getting some tests in place so that I could switch to a test driven approach. I decided to use mocha and chai for running and defining the tests (I’ll write a separate blog post on how I used them).

These can then be executed locally using the npm test command and they are executed every time I push to GitHub by the Travis CI service, check out the results of the latest build here.

Conclusion

So far the framework is pretty basic, but with the testing framework now in place I can focus on adding new features. I plan to raise issues and milestones in GitHub to help track the progress to the initial 1.0 release. This will hopefully include most of the file component features and perhaps some http as well.

The code for camel.js is available on my GitHub. Feel free to do a pull request and add some features!


Comments