I’ve been a Microsoft developer since I started programming straight out of college and I know there are many others out there just like me. It’s been a comfortable space that has grown steadily over the past 10+ years. However, in the last 3-5 years or so, I branched out of my Microsoft comfort zone and dipped my toes into other languages, platforms and frameworks such as iOS development, Android, Ruby on Rails, PHP and most recently Node.js.
There’s been a lot of debate since Node’s arrival as to whether or not this is a step backwards for software development. JavaScript on the server? You mean the almost 20-year-old scripting language that I’m still using on the client but only because jQuery makes it look easy? Yes, that JavaScript!
Likewise, if you came from a Classic ASP development background like me, then you probably knew that with Classic ASP, you usually had 2 languages to pick from: VBScript (the most common) and JScript (Microsoft’s Implementation of ECMAScript). Other languages such as PerlScript, Python and others could also be installed via third-party Active Scripting Engines, but the two main ones that came built-in were VBScript and JScript/JavaScript.
While most folks (myself included) used VBScript for Classic ASP development, JScript (JavaScript) was (and still is) an interesting option. It’s dynamic like VBScript, but more structured and case-sensitive like C#. Personally, I always liked JavaScript because of this blend between its dynamic nature and its structured C roots. If you’re in a corporate Microsoft-shop environment like I was up until a year and a half ago, you may still find yourself maintaining some legacy Classic ASP systems. If so, I encourage you to experiment with JavaScript and Classic ASP. It will prepare you for getting used to JavaScript on the server with Node.js. If you’re strictly a .NET developer, think a malleable C# without so many rules. To use JavaScript for Classic ASP, you simply add the following language directive to the top of your .asp files:
<%@ language="javascript"%>
And then you can do something like:
<% // CustomerRepository class var CustomerRepository = function() { this.save = function(customer) { // insert/update in db }; this.findById = function(id) { // retrieve from db by id }; this.delete = function(id) { // delete from db by id }; }; var customerRepository = new CustomerRepository(); // In Classic ASP or other programming languages, this would block the current thread until the database returned the customer var customer = customerRepository.findById(12345); %>
If you’re a C# developer, this probably looks very familiar. It’s not statically typed like C#, but the syntax is familiar and clean.
Now, as far as Node.js goes, this same “class” could be made into a simple Node.js module with some minor changes:
- First, we’d remove the angle-bracket percent (<%%>) tags
- Next, we’d rename the file to CustomerRepository.js and export this as a module
- Finally, using Node’s callback convention, we’d add a callback parameter to our methods like below. Or, we could use an event-driven approach by inheriting from Node’s EventEmitter.
Then, we’d end up with:
// CustomerRepository class var CustomerRepository = function() { this.save = function(customer, callback) { // insert/update in db }; this.findById = function(id, callback) { // in a real app, we'd kick off some I/O and retrieve the customer from // a database, web service or somewhere else // since this isn't a real app, we need to throw this on the event loop/queue // so as not to block the current thread. We do that using process.nextTick // if I hadn't wrapped this in process.nextTick, then this would actually // fire immediately which would block Node's main thread which is a // bad thing since there's only one of them!!! process.nextTick(function() { callback({ id:123456, name:'Joe Customer', email:'[email protected]' }); }); }; this.delete = function(id, callback) { // delete from db by id }; }; module.exports = new CustomerRepository();
Using Node’s require statement (akin to include in Classic ASP or using in C#), we could then import this module like so:
var customerRepository = require('./lib/CustomerRepository.js'); // In Node.js this will not block the current thread since this is an I/O operation customerRepository.findById(12345, function(err, customer){ if (err) { console.log('Oh no, something bad happened: ' + err); } else { console.log('Yippee! We got a customer back: ' + customer.name); // now, do something with the customer object } });
Nothing revolutionary here. My point is to simply show you that there is nothing inherently magical or complicated about JavaScript on the server. It’s still the same JavaScript you use on the client today with libraries like jQuery etc. and the same JavaScript you could have used with Classic ASP 15 years ago.
However, the part that does make JavaScript magical on the server is Node. It’s built on top of Google Chrome’s V8 JavaScript Engine. For those of you that are using Chrome, you know how fast Google Chrome is. Well, V8 is the magic behind Chrome’s speed performance when it comes to JavaScript.
What Node does is bring that speed and performance to the server in the form of a fast, lightweight, single-threaded event loop. Wait! Hold Up! Did you say “single-threaded?” Yes, I said “single-threaded.” Rather than spawn new threads or use a pool of worker threads to service new requests, Node takes a different approach to performance in the form of a non-blocking evented model that is designed to be asynchronous. This is good for developers because it means we don’t have to worry about thread pool management, sync locks, mutexes, race conditions and the joy (sarcasm) that is debugging multi-threaded programs. However, in order for Node to allow a single thread to handle multiple concurrent requests, you can never allow the main thread to wait on blocking, synchronous or CPU-bound operations. Note the phrase “you can never allow” in the previous sentence. Node will not prevent you from writing blocking, synchronous or high CPU-bound operations. Node will handle making I/O operations non-blocking for you, but for anything else, It is your responsibility as the developer to make sure you are writing non-blocking, asynchronous code. Node simply gives you the framework and conventions for doing so, but it does not mandate this. You read more about how Node works here.
Still, you may ask, “Why JavaScript on the server?” Well, if you’re doing web development these days you are probably using JavaScript on the client for things like form validation, DOM manipulation, ajax, lazy content-loading, etc. If you’re working with web services, you have probably consumed JSON through an API like Twitter, Facebook or maybe you’ve rolled your own. So, you’re using JavaScript on the client. JavaScript in transport (in the form of JSON) and you may even be storing some JSON on the server whether as serialized data in a relational-database such as SQL Server, Oracle, MySQL or PostGres. Or, maybe you’re using a NoSQL database such as MongoDB, CouchDB or even Azure Table Storage.
So, if you’re using JavaScript on the client, JavaScript in-transport and JavaScript for persistence. It only begs the question, should JavaScript be used on the server?
Node’s answer is “yes” and many developers have come to that same conclusion (end-to-end JavaScript) and that is why Node.js has gone from an obscure project just a few short years ago to one of the most actively followed projects on GitHub today.
Now, we get to the part of why you should care about Node.js as a Microsoft / .NET developer.
Microsoft has taken notice of Node’s growing popularity and its merits and they have worked with the Node.js community on Windows support for node and IIS support through iisnode. Microsoft has embraced Node.js as a first-class citizen in Windows Azure, going from MIA a little over a year ago to being listed as the first language (below .NET) on their Window Azure Developer Center, ahead of Java, PHP and Python.
Node.js on Azure is actually a great story that has many benefits aside from running Node yourself.
As this article points out, Microsoft doesn’t adopt outside technologies that aren’t established. Just like their official support for jQuery, Microsoft’s support of Node.js signifies a shift from “cool fringe technology that carries too much risk to use on a real project” to “something I should at least start becoming familiar with in case it becomes the next jQuery.”
Despite this, you may ask yourself, “Is JavaScript-development the direction I want to take my career?” Well, look no further than Windows 8 and its support for building Metro apps with HTML5, CSS and…..JavaScript. I submit that just like writing Classic ASP with JavaScript wouldn’t make you any less of a Microsoft developer 15 years ago, writing Node.js apps with JavaScript won’t make you any less of a Microsoft developer today. JavaScript is here to stay. If you don’t like the language or its syntax, then take a look at CoffeeScript, a little syntactic sugar over JavaScript.
Who knows, your next project might be an HTML5, CSS and JavaScript Windows 8 Metro App that communicates with a Node.js server running on Windows Azure backed by MongoDb. Sneak in a little JavaScript into that Classic ASP app you’re still supporting 12 years later and you’ll feel right at home.
If you’re a Microsoft developer, let me know what you think of Node.js in the comments.
Happy JavaScripting!