A chat application (Now.js + Node.js) — 12 lines of code
- 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.
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
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.
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.
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.
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.
Want to try this out? Here are the steps:
- Download Node.js (not currently available for Windows)
- Prepare a directory for the necessary files.
- 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!