My Node.js Perspective
After spending more than ten years creating web applications in Java,
I finally chose to build one using Node.js, and thought I'd
share the results…
especially since I keep running across various perspectives on Node-base projects.
First a bit of background on the purpose and requirements for the project.
I was given a team of junior engineers in China, with Java
experience. In fact, except for one engineer, Java was the only
language they knew. (Yes, graduating software engineers who only know
one computer language continually stuns and amazes me).
In order to guarantee continued funding, we scheduled the project's
alpha release three months after we began. This would challenge a team
of seasoned veterans, much less my young team.
Some of the requirements for the product were:
- Work on mobile devices and desktops alike
- Interact with user dynamically (like a real desktop application)
- Run in the same cloud it'd control
Oh, and I'd also have to teach them Agile development methodologies.
I admit, I didn't have much hope.
Why on Hell?
With the requirement of a dynamic web application that could work on
an iPad, clearly we'd be building a JavaScript client application.
So I'd have to teach some of my engineers JavaScript.
With a short development cycle, I didn't want my team to spend
precious cycles with Java ornamentation and the
all-but-impossible-to-troubleshoot Spring configurations. Scripting
languages, even on the server, are good choices for prototype
projects, so which language/framework should I choose?
While I would like to have chosen Groovy, Ruby was a better choice,
since the other back-end teams chose to work with the same language
as Cloud Foundry.
Choosing Ruby would meant that I would have to split my team into the
front-end JavaScript team and the back-end team… but not if I
chose the same language for both.
Yep, that was the final piece of straw that swayed us.
Training
We flew to China to meet and train our teams. The main points to
my lessons were:
- You don't know JavaScript. You must learn JavaScript.
- Asynchronous and functional programming is different.
- Our only savior will be automated tests.
After teaching them Agile development, Git, and REST, I began with a
short history of JavaScript shamelessly stolen from Mr. Crockford.
I even made them all read his book, JavaScript: The Good Parts.
However, I knew that the asynchronous nature of Node would prove a
challenge to engineers with a deficient education (I don't blame the
Chinese universities, as it seems that American universities are
churning out poor graduates as well).
I've always believed the best way to learn is to teach, so after each
scrum, we'd alternate teaching each other a new concept. We called
them 10 Minute Sharing episodes, as the time-limit needed to be in
the title.
Infrastructure
I next built out a JavaScript-oriented infrastructure, which is
something that Java developers take for granted, like:
A young technology, like Node.js, surprised me with such a
mature community of support.
Many of the deficiences found, I easily remedied by either
forking and fixing projects (like updating Mocha) or
wrapping them up in a new project (like jake-utils and node-idocs).
Results
Simply put: We made our alpha release with few bugs,
and acceptable performance metrics.
Our unit tests covered 100% of the code.
The product even looked good.
Sure, the passion and eagerness of my team key, but I also
attribute Node.js for part of the success.
Code written in Node is considerably simpler than client-side
JavaScript, and with easily written unit tests,
we often refactor initial code to more straight-forward solutions.
Keep in mind:
- Variables in a node module are not global, so data abstraction is a given.††To make a variable or function available to other modules, you have to explicitely export it or assign it to the
globals
variable.
- The NPM module framework is pretty good; better than any other
dynamic language I've used. It means you don't have to have stupid
kludges like
rvm
.
- Each module follows the singleton pattern and maintain its own internal state in a module-level scope.††See my essay for details on this feature.
We had our share of gotchas, especially since asynchronous coding
requires a new brain. However, we easily identified these sorts of *race
conditions* and soon, enlightenment arrived, and we ate callbacks
for our lunch and drank event emitters for our tea.
The Cloud and Node
Node fits well in a world of the cloud, that is, an architecture built
from micro-server instances:
- Each instance has a small, dedicated purpose
- Each instance holds no state
- Loosely coupled through either REST interfaces or Redis queues
Sure, Python, Ruby and other dynamic languages work well in the cloud
with this architecture, however, Node fit well in this world.
Final Thoughts
The project was great fun, and I fell in love with JavaScript and
Node, and found it to be a great prototyping system.
Would I build an enterprise solution in Node.js? Hrm, I highly doubt it.
First, I sorely miss types.
Also 100% code coverage doesn't mean as much as it does with a Java project.
You really need 300% to cover enough negative tests of passing in arrays, strings and objects.
Second, a single Node.js app isn't that performant‡‡Have we decided on a spelling for this new word? and a cloud-based architecture even more-so.
While the resulting code isn't that fast with huge loads,
I found my Node.js project to be
fast to code,
easy to maintain, and
coherent to organize code functionality and structure (given Node's module system).
Now, the dynamic client-side part of the project… well, that is a whole other story that I should tell someday.
Tell others about this article: