This section will take you through a basic Node program before we move on to more in-depth programs.
One of the things that’s often hard to understand about Node.js is that, in
addition to being a server, it’s also a runtime environment in the same
way that Perl, Python, and Ruby are. So, even though we often refer to
Node.js as “server-side JavaScript,” that doesn’t really accurately
describe what Node.js does. One of the best ways to come to grips with
Node.js is to use Node REPL (“Read-Evaluate-Print-Loop”), an interactive
Node.js programming environment. It’s great for testing out and learning
about Node.js. You can try out any of the snippets in this book using
Node REPL. In addition, because Node is a wrapper around V8, Node REPL is an ideal place to easily try out
JavaScript. However, when you want to run a Node program, you can use
your favorite text editor, save it in a file, and simply run node filename.js
. REPL is a great learning and
exploration tool, but we don’t use it for production code.
Let’s launch Node REPL and try out a few bits of JavaScript to warm up (Example 1-6). Open up a console on your system. I’m using a Mac with a custom command prompt, so your system might look a little different, but the commands should be the same.
Note
The first line, which evaluates to
false
, is from http://wtfjs.com, a collection of weird and amusing
things about JavaScript.
Having a live programming environment is a really great learning tool, but you
should know a few helpful features of Node REPL to make the most of it.
It offers meta-commands, which all start with a period (.
). Thus,
.help
shows the help menu, .clear
clears the current context, and .exit
quits Node REPL (see Example 1-7).
The most useful command is .clear
,
which wipes out any variables or closures you have in memory without the
need to restart REPL.
When using REPL, simply typing the name of a
variable will enumerate it in the shell. Node tries to do this
intelligently so a complex object won’t just be represented as a
simple Object
, but
through a description that reflects what’s in the object (Example 1-8). The main exception to this involves
functions. It’s not that REPL doesn’t have a way to
enumerate functions; it’s that functions have the tendency to be very
large. If REPL enumerated functions, a lot of output could scroll by.
REPL gives us a great tool for learning and experimentation, but the main application of Node.js is as a server. One of the specific design goals of Node.js is to provide a highly scalable server environment. This is an area where Node differs from V8, which was described at the beginning of this chapter. Although the V8 runtime is used in Node.js to interpret the JavaScript, Node.js also uses a number of highly optimized libraries to make the server efficient. In particular, the HTTP module was written from scratch in C to provide a very fast nonblocking implementation of HTTP. Let’s take a look at the canonical Node “Hello World” example using an HTTP server (Example 1-9).
The first thing that this code does is
use require
to include the
HTTP library into the program. This concept is used in
many languages, but Node uses the CommonJS module format, which we’ll talk about more in
Chapter 8. The main thing to know at this point is
that the functionality in the HTTP library is now assigned to the
http
object.
Next, we need an HTTP server. Unlike some
languages, such as PHP, that run inside a server such as Apache, Node
itself acts as the web server. However, that also means we have to
create it. The next line calls a factory method from the HTTP module
that creates new HTTP servers. The new HTTP server isn’t assigned to a
variable; it’s simply going to be an anonymous object in the global
scope. Instead, we use chaining to initialize the server and tell it to
listen on port 8124
.
When calling createServer
, we passed an anonymous function as an argument. This function
is attached to the new server’s event listener for the request
event. Events
are central to both JavaScript and Node. In this case, whenever there is
a new request to the web server, it will call the method we’ve passed to
deal with the request. We call these kinds of methods
callbacks because whenever an event happens, we “call back” all the
methods listening for that event.
Perhaps a good analogy would be ordering a
book from a bookshop. When your book is in stock, they call
back to let you know you can come and collect it. This
specific callback takes the arguments req
for the request object and res
for the response object.
Inside the function we created for the
callback, we call a couple of methods on the res
object. These calls modify the response.
Example 1-9 doesn’t use the request, but
typically you would use both the request and response objects.
The first thing we must
do is set the HTTP response header. We can’t send any actual response to the client without
it. The res.writeHead
method does
this. We set the value to 200
(for
the HTTP status code “200 OK”) and pass a list of HTTP headers. In this
case, the only header we specify is Content-type
.
After we’ve written the HTTP header to the
client, we can write the HTTP body. In this case, we use a single method
to both write the body and close the connection. The end
method closes the HTTP connection, but since we also passed it a
string, it will send that to the client before it closes the
connection.
Finally, the last line of our example uses
the console.log
. This simply prints information to stdout
, much like the browser counterpart
supported by Firebug and Web Inspector.
Let’s run this with Node.js on the console and see what we get (Example 1-10).
Example 1-10. Running the Hello World example
Enki:~ $ node
> var http = require('http');
> http.createServer(function (req, res) {
... res.writeHead(200, {'Content-Type': 'text/plain'});
... res.end('Hello World\n');
... }).listen(8124, "127.0.0.1");
> console.log('Server running at http://127.0.0.1:8124/');
Server running at http://127.0.0.1:8124/
node>
Here we start a Node REPL and type in the
code from the sample (we’ll forgive you for pasting it from the
website). Node REPL accepts the code, using ...
to indicate that you haven’t completed the
statement and should continue entering it. When we run the console.log
line, Node REPL prints
out Server running at
http://127.0.0.1:8124/
. Now we are ready to call our Hello
World example in a web browser (Figure 1-1).
It works! Although this isn’t exactly a stunning demo, it is notable that we got Hello World working in six lines of code. Not that we would recommend that style of coding, but we are starting to get somewhere. In the next chapter, we’ll look at a lot more code, but first let’s think about why Node is how it is.
Get Node: Up and Running now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.