Node.js is an exciting, multi-platform framework built around the JavaScript programming language which has been gaining support by developers over the past few months. In this article, I’ll give a summary of why this platform is so attractive to a growing number of programmers, and guide you through a brief example application.
A chat application (Now.js + Node.js) — 12 lines of code
More and more developers are choosing to build their server-side applications in Node.js / JavaScript. Here are a few very good reasons why you should give Node.js a chance.
- It’s unbelievably fast. Built around Google’s V8 JavaScript Engine, Node scripts manage to blow scripts of pretty much every other interpreted language out of the water. Check out some benchmarks to see what I mean: JavaScript V8 versus PHP, vs. Ruby, vs. Python, and vs. Perl.
- The core code is designed to run asynchronously / in parallel. Most, if not all, of the Node.js standard library can be used asynchronously. This means that all sorts of operations — file reads and writes, database queries and updates, et cetera — can run in parallel, independent of each other. Node.js, therefore, is extremely capable when low response times and high concurrency are necessary.
- The back-end language matches the front-end language. Node.js sites are able to use the JavaScript language in both the front-end and the back-end. This feature has led to all sorts of interesting inventions. For example, I recently discovered Now.js, a library which allows code running in the browser to directly call functions defined in the server code, without any explicit AJAX or JSON requests. I recommend you check out the Now.js site and see for yourself the power of this feature of Node.js.
Okay, let’s get started with a short demonstration of a Node.js server. To demonstrate some of the language features, we’ll establish several goals:
- Respond to HTTP requests. Obviously, since this is a server, right?
- Send HTTP headers in responses. This is necessary to have the client’s browser parse and display our response correctly.
- Serve a file in the HTTP response. This will demonstrate Node.js’s asynchronous I/O design.
We’ll start by using the require method to import some necessary libraries:
- fs (filesystem), which allows us to perform basic asynchronous file I/O operations
- http, which establishes a basic HTTP server
[gist id=877867 file=server_1.js]
Simple, right? This is basically the same as requires / imports in common high-level languages like Python and Ruby. The principal difference is the assignment that occurs in each of these statements. To put it simply, importing each module like so keeps all of its contents in a namespace of sorts. By placing all of the fs module’s attributes and methods inside a variable called fs, we can be certain that nothing in the global scope will be overwritten. For example, if we included two modules which had classes with the same names, they would not overwrite each other, as they would be stored inside different variables. For this reason, modules are imported into local variables rather than into the global scope.
Phew! After that lengthy explanation, it’s time to get to the meat of our little web app here.
[gist id=877867 file=server_2.js bump=1]
We’ve added a call to the createServer function of the http module. This simple function accepts a single parameter: a callback function which is called whenever a request to the server is received. You can see that the anonymous function we provide has two parameters: request and response. When the server invokes this function, the provided request variable will contain information about the HTTP request (headers, data, and so on), while the given response variable will contain several methods that we can use to reply to the HTTP request.
We then chain this createServer call to the listen method, which tells the created HTTP server to begin listening on a certain host and port — in this case, 127.0.0.1:8080.
[gist id=877867 file=server_3.js bump=2]
We now have added some basic calls to the response object. In short:
- writeHead begins the HTTP response to the client by sending a 200 OK code, along with a Content-Type header that lets the client know that we’ll be sending plain text as a response.
- end sends any last data, closes the response, lets the server know that we’re all done here.
Okay, this is good stuff, but let’s push things a little further by returning the contents of a file rather than a simple static string.
[gist id=877867 file=server_4.js bump=3]
Now we have the previous response code enclosed inside a second callback function. This function is provided to fs‘s readFile method, which reads a given file asynchronously and calls the provided function when it’s finished. Notice that the anonymous function here accepts two parameters here: err, which we throw if it is defined, and data, which contains the raw file contents. All that changed in the response code was in the write call: we now provide the file data (converted to a string) as the response instead of a static string.
That’s it! As long as we have a file named response.txt in the same file as our server JavaScript, this will work perfectly.
Want to try this out? Here are the steps:
- Download Node.js (not currently available for Windows)
- Prepare a directory for the necessary files.
- Create the files. Use the final server code from above and place it in a JavaScript file. Name it whatever you’d like — server.js, maybe? Create a file called response.txt in the same directory as the server script, and put some text in it, like “Hello world from a text file!”
- Launch the server in your terminal. Change to the directory you created and run node server.js
(Change “server.js” to the name you used for your server code.) - Try it out! Visit 127.0.0.1:8080 in a web browser and you should see the contents of the response.txt file you created appear on the page.
I hope you enjoyed and learned something from this introduction to Node.js. I understand that 99% of web applications are not this simple, and we will be creating tutorials in the near future that will cover more complicated tasks, such as URL routing and database access. Please subscribe to the Labs blog to receive updates about our future Node.js tutorials. Leave a comment below as well if you’d like to let us know what you think about this article!