This is the first post in a series of 3 about my experiences with Node.js. I will follow up with posts that including my experiences porting a RESTful service from Java, some benchmarks comparing the Node.js service and the Java service and my final thoughts from these experiences.
My tests and information are based on the v0.6.8 of NodeJS. Between my initial research and the writing of this article, there have been seven separate releases of Node.js from Joyent in the span of 6 weeks. Four of these updates were to the stable v0.6 track included updates and bug fixes. Initially, I installed v0.6.6 while researching. Durring my testing and development, v0.6.7 v0.6.8, v0.6.9, and v0.6.10 were released. I went ahead and upgraded my Node.js instance to v0.6.7 and then to v0.6.8 without any issues. Meanwhile, there were also releases of the unstable v0.7.0, v0.7.1, and v0.7.2 update which are running the latest V8 engines and are including more modules natively as well as bug fixes. For more details on these releases, visit the Node.js blog.
My investigation into node will attempt to answer these key questions:
- What is Node.js and how can we explain it to non-technical managers?
- How does it perform compared to something already in production?
- How can we use Node.js and what problems does it solve?
- And ultimately… is it ready to consider for production use?
What is Node.js?
Over the last year, the Node.js community has taken off. Joyent has been releasing updates every few weeks to the Node.js server and there are numerous plugins and frameworks available to assist with application building. Fortunately, there are many resources freely available to research and get a better understanding of the Node server. I found plenty of material and spent a few weeks reading, watching web videos, learning from tutorials and tinkering with some examples.
Scalability was only a minor focus of my Node.js research, but turned out to be one of the more difficult topics to get information on. The definition of scalability from Wikipedia as described by André B. Bondi, “Characteristics of scalability and their impact on performance”, “is the ability of a system, network, or process, to handle growing amount of work in a capable manner or its ability to be enlarged to accommodate that growth.” The Node.js site talks a big game about the scalability of the server. They discuss it in its tagline, but just how do you really scale a Node.js server environment? Unfortunately, I don’t think their site answers this very well.
The first answers I found included the obvious solution to load balance multiple machines. How can we solve the problem of our application handling a quazillion gagillion simultaneous requests? Throw another server at it. With the power of machines today and the low resource footprint of Node.js leaves a lot of wasted power. Other answers to scalability include solutions module-based solutions like cluster, which allow an application the ability to scale across multiple CPU cores and take advantage of more of the host machine’s resources.
It took a while to sift through all of them and find out what is mature enough to get my attention. Unfortunately, many of these projects were either incomplete or not compatible with the latest versions of Node.js. Using trial and error, was about the only way to know if some of these modules were compatible with one another or the current version of Node. There were also many issues with documentation, most of which was pulled from README text files out on GitHub and not very detailed.
Extending the search for modules through Google returned many resources, but most results suffered from the same issues. Researching the modules may have been one of the most difficult and disappointing parts of working with Node.js. It drastically slowed down my research and was a turn off to being an early adopter. The community encourages developers to publish incomplete work with little documentation. This is one thing that will need to change before it will be a realistic option for enterprise environments.
Preparing to Build
The first thing any technologist should do when learning a new technology is go into it with an open mind. Be careful on comparing two technologies one for one. Recognize what makes it different, rather than what makes it the same as other technologies you are familiar with. All too often I see developers assume what they know from one language or technology applies in another technology. This can be dangerous. It can also be confusing when porting the language from one context to another.
Fortunately, there are plenty of frameworks to chose from to simplify different tasks in Node. These frameworks had many different focusses, support different add-ons, had utility functionality for different technologies including Sockets and DNS. For my research, I was focused on finding an application framework that would assist with creating a HTTP server and would easily handle routing.
In the end, I chose ExpressJS. I found it to be mature and robust web development framework. It offered many features to simplify my development and get my application set up quickly, including many view features and enhanced routing. The framework also had optional plugin modules to assist in creation of resources which greatly simplified my goals of a RESTful interface. I had no issues with installing and running Express directly form the tutorials and it includes a well documented API. From here I used Express to build my first “Hello World” application and it ran with no issues.
My next task was to find a module to support communication with a MySQL database. I originally looked at the node-mysql adapter to handle SQL queries. This was basic and worked very well. I also wanted to look into a MySQL-ready Object-relational mapping (ORM) module to assist with handling data. I quickly stumbled across node-orm but struggled to get it to work with the latest version of Node.js. After a few more Google searches, I found Sequelize. The Sequelize project is a well documented ORM project that supports MySQL. It supports a variety of ORM features that includes models, validation and relationship handling.
The next steps are to take my research, the framework and the modules I have found and recreate an existing application created using a different mature technology. It could be argued that it is not a good test to compare two different technologies who may have different strengths and weaknesses. However in this case, the application I will be recreating for the test is a RESTful JSON service which by definition should be a perfect fit for Node.js.
View the continuation of my Experiences with Node.js series: Porting a RESTful Service Written in Java.