Node.js - Oh My JS: The Best JavaScript Articles (2014)

Oh My JS: The Best JavaScript Articles (2014)

Node.js

Understanding event loops and writing great code for Node.js

Original Article

http://developer.yahoo.com/blogs/ydn/part-1-understanding-event-loops-writing-great-code-11401.html

Tom Hughes-Croucher, developer.yahoo.com/blogs

As usual JSConf.eu was one of the best conferences I’ve been to this year. It’s always a delight to hang out with some of the smartest JavaScript coders on the planet, and doing it in the very trendy city of Berlin was a nice bonus. There are a few great recaps of JSConf so I’m not going to focus on those; instead I’m going to expand the talk I gave.

Programming inside an event loop is something most programmers only have a passing familiarity with. Node.js is quickly gaining traction as a very popular event loop-based server for JavaScript. It gives people the ability to write JavaScript on the server, which has access to things like the HTTP stack, TCP, file I/O, and databases. However the kind of programs that we write in this context tend to be very different from the kind of programs we write for browser-side applications or sites.

In the browser, the bulk of the program tends to be involved with setting up the user-interface, and then there are some small event callbacks that are enacted — most typically, based on user interaction with the browser. For example, when the user clicks Submit on a form, we intercept the click and validate their submission.

There is an important point here: in most browser programming, programmers are only dealing with events caused by the user, and the user can only do so many things at once. Moreover the callbacks for those events tend to be very discrete and don’t cause other events. Some libraries, such as YUI, have custom event support. But it is often thought of an advanced feature.

On the server, however, there isn’t a user to drive a variety of interactions. Instead we have a whole range of reactions to take on many different kinds of events. Node.js takes the approach that all I/O activities should be non-blocking (for reasons we’ll explain more later). This means that all HTTP requests, database queries, file I/O, and so on, do not halt execution until they return. Instead they run independently and then emit an event when the data is available.

This means that programming in Node.js has lots of callbacks dealing with all kinds of I/O and then initiating other callbacks for other kinds of I/O. This is a very different from browser programming. There is still a certain amount of liner setup, but the bulk of the code involves dealing with callbacks.

Event drivenBecause of these different programming styles, we need to look for patterns to help us effectively program on the server. That starts with the event loop, so let’s take a look at that in more depth.

I think that most people intuitively get event-driven programming because it’s like everyday life. Imagine you are cooking. You are chopping a bell pepper and a pot starts to boil over. You finish the slice you are doing, and then turn down the stove. In daily life, we are used to having all sorts of internal callbacks for dealing with events, and yet, like JavaScript, we only do one thing at once.

Yes, yes, I can see you are rubbing your tummy and patting your head at the same time, well done. But, if you try to do any serious activities at the same time, it goes wrong pretty quick. This is like JavaScript. It’s great at letting events drive the action, but it is “single-threaded” so only one thing happens at once.

Another way to think about this event loop is a post (or mail) man. To our event-loop postman, each letter is an event. He has a stack of events to deliver in order. For each letter (event) the postman gets, he walks to the route to deliver the letter. The route is the callback function assigned to that event (sometimes more than one). However, critically, since our mailman only has a single set of legs, he can only walk a single code path at once.

Sometimes, while the postman is walking a code route someone will give him another letter. This is because the callback function he is code walking has emitted an event. In this case the postman delivers the new message immediately (after all someone gave to him directly instead of going via the post office so it must be urgent). The postman will diverge from his current code path and walk to the code path to deliver the new event. He then carries on walking the original event that emitted the event he just walked.

Let’s look at another example. Let’s give the postman a letter to deliver that requires a gate to be open. He gets there and the gate is closed, so he simply waits and tries again, and again. He’s trapped in an endless loop waiting for the gate to open. But if there is a letter on the stack that will ask someone to open the gate so the postman can get through, surely that will solve things, right?

Unfortunately it won’t, because the postman will never get to deliver the letter because he’s stuck waiting endlessly for the gate to open. This is because the event that opens the gate is external from the current event callback. If we emit the event from within a callback, we already know our postman will go and deliver that letter before carrying on. However, when events are emitted external to the currently executing piece of code, they will not be called until that piece of code has been fully evaluated to its conclusion.

We can use this to write a piece of code that creates a loop that Node.js (or a browser) will never break out of:

1 EE = require('events').EventEmitter;

2 ee = new EE();

3

4 die = false;

5

6 ee.on('die', function() {

7 die = true;

8 });

9

10 setTimeout(function() {

11 ee.emit('die');

12 }, 100);

13

14 while(!die) {

15 }

16

17 console.log('done');

In this example, console.log will never be called because the while loop stops Node from ever getting chance to callback the timeout and emit the 'die' event.

This is a really important piece of information, because while it’s unlikely we’d program a loop like this that relies on an external condition to exit, it clearly illustrates how Node.js can only do one thing at once. And getting a fly in the ointment can really screw up the whole server.

Let’s look at the standard Node.js code for creating an HTTP server:

1 var http = require('http');

2 http.createServer(function (req, res) {

3 res.writeHead(200, {'Content-Type': 'text/plain'});

4 res.end('Hello World\n');

5 }).listen(8124, "127.0.0.1");

6 console.log('Server running at http://127.0.0.1:8124/'

This code is the 101 example from the Node.js web site. It creates an HTTP server using a factory method in the http library. The factory method creates a new HTTP server and attaches a callback to the 'request' event. The callback is specified as the argument to the createServer.

What’s interesting here is what happens when this code is run. The first thing Node.js does is run the preceding code from top to bottom. This can be considered the ‘setup’ phase of Node programming. Since we attached some event listeners, Node.js doesn’t exit, but waits for an event to be fired. If we didn’t attach any events, then Node.js would exit as soon as it had run the code.

So what happens when we get an HTTP request? When an HTTP request is sent to the server, Node.js emits the ‘request’ event that causes the callbacks attached to that event to be run in order. In this case there is only one callback, the anonymous function we passed as an argument tocreateServer. Let’s assume it’s the first request the server has had since it setup. Since there is no other code running, the 'request' event is emitted and the callback is just run. It’s a very simple callback and it runs pretty fast.

Let’s assume that our site gets really popular and we get lots of requests. If, for the sake of argument, our callback takes 1 second, then if we received 2 requests at the same time, they can’t both be run at once, and the second request isn’t going to be acted on for another second or so. Obviously, a second is a really long time, but as we start to look at real-world applications, the problem of blocking the event loop becomes more dangerous as we can see the damage it could have on users.

The upshot of this is that we want to keep Node.js as event-driven and non-blocking as possible. In the same way that an I/O event that can be slow should use callbacks to indicate the presence of data Node.js can act on, the Node.js program itself shouldn’t be written in such a way that any single callback ties up the event loop for extended pieces of time.

The operating system kernel actually handles the TCP connections to clients for the HTTP server, so there isn’t a risk of not accepting new connections. But there is a real danger of not acting on them.

This means that we should employ two strategies for writing Node.js servers:

· Once set up has been completed, make all actions event driven

· If Node.js is required to process something that will take a long time, consider delegating with web workers

Taking the event-driven approach works effectively with the event loop — I guess the name is hint it would — but it’s also important to write event-driven code in a way that is easy to read and understand.

In the previous example, we used an anonymous function as the event callback. This makes things hard in a couple of ways. Firstly, we have no control over where the code lives; the anonymous function must live where it is attached to the event either via a factory method or the on method of an EventEmitter. The second issue is debugging: if everything is an anonymous event, it can sometimes be hard to distinguish similiar callbacks from each other when an exception occurs.

Callback Hell

A guide to writing asynchronous javascript programs

Original Article

http://callbackhell.com

Max Ogden, github.com/maxogden

What is “callback hell”?

Asynchronous javascript, or javascript that uses callbacks, is hard to get right intuitively. A lot of code ends up looking like this:

1 fs.readdir(source, function(err, files) {

2 if (err) {

3 console.log('Error finding files: ' + err)

4 } else {

5 files.forEach(function(filename, fileIndex) {

6 console.log(filename)

7 gm(source + filename).size(function(err, values) {

8 if (err) {

9 console.log('Error identifying file size: ' + err)

10 } else {

11 console.log(filename + ' : ' + values)

12 aspect = (values.width / values.height)

13 widths.forEach(function(width, widthIndex) {

14 height = Math.round(width / aspect)

15 console.log('resizing ' + filename + 'to ' + height + 'x' + height)

16 this.resize(width, height).write(destination + 'w' + width + '_' + fi\

17 lename, function(err) {

18 if (err) console.log('Error writing file: ' + err)

19 })

20 }.bind(this))

21 }

22 })

23 })

24 }

25 })

See all the instances of function and })? Eek! This is affectionately known as callback hell.

Writing better code isn’t that hard! You only need to know about a few things:

Name your functions

Here is some (messy) browser javascript that uses browser-request to make an AJAX request to a server:

1 var form = document.querySelector('form')

2 form.onsubmit = function(submitEvent) {

3 var name = document.querySelector('input').value

4 request({

5 uri: "http://example.com/upload",

6 body: name,

7 method: "POST"

8 }, function(err, response, body) {

9 var statusMessage = document.querySelector('.status')

10 if (err) return statusMessage.value = err

11 statusMessage.value = body

12 })

13 }

This code has two anonymous functions. Let’s give em names!

1 var form = document.querySelector('form')

2 form.onsubmit = function formSubmit(submitEvent) {

3 var name = document.querySelector('input').value

4 request({

5 uri: "http://example.com/upload",

6 body: name,

7 method: "POST"

8 }, function postResponse(err, response, body) {

9 var statusMessage = document.querySelector('.status')

10 if (err) return statusMessage.value = err

11 statusMessage.value = body

12 })

13 }

As you can see naming functions is super easy and does some nice things to your code:

· makes code easier to read

· when exceptions happen you will get stacktraces that reference actual function names instead of “anonymous”

· allows you to keep your code shallow, or not nested deeply, which brings me to my next point:

Keep your code shallow

Building on the last example, let’s go a bit further and get rid of the triple level nesting that is going on in the code:

1 function formSubmit(submitEvent) {

2 var name = document.querySelector('input').value

3 request({

4 uri: "http://example.com/upload",

5 body: name,

6 method: "POST"

7 }, postResponse)

8 }

9

10 function postResponse(err, response, body) {

11 var statusMessage = document.querySelector('.status')

12 if (err) return statusMessage.value = err

13 statusMessage.value = body

14 }

15

16 document.querySelector('form').onsubmit = formSubmit

Code like this is less scary to look at and is easier to edit, refactor and hack on later.

Modularize!

This is the most important part: Anyone is capable of creating modules (AKA libraries). To quote Isaac Schlueter (of the node.js project): “Write small modules that each do one thing, and assemble them into other modules that do a bigger thing. You can’t get into callback hell if you don’t go there.”

Let’s take out the boilerplate code from above and turn it into a module by splitting it up into a couple of files. Since I write JavaScript in both the browser and on the server, I’ll show a method that works in both but is still nice and simple.

Here is a new file called formuploader.js that contains our two functions from before:

1 function formSubmit(submitEvent) {

2 var name = document.querySelector('input').value

3 request({

4 uri: "http://example.com/upload",

5 body: name,

6 method: "POST"

7 }, postResponse)

8 }

9

10 function postResponse(err, response, body) {

11 var statusMessage = document.querySelector('.status')

12 if (err) return statusMessage.value = err

13 statusMessage.value = body

14 }

15

16 exports.submit = formSubmit

The exports bit at the end is an example of the CommonJS module system, which is used by Node.js for server side javascript programming. I quite like this style of modules because it is so simple – you only have to define what should be shared when the module gets required (that’s what the exports thing is).

To use CommonJS modules in the browser you can use a command-line thing called browserify. I won’t go into the details on how to use it here but it lets you use require to load modules into your programs.

Now that we have formuploader.js (and it is loaded in the page as a script tag) we just need to require it and use it! Here is how our application specific code looks now:

1 var formUploader = require('formuploader')

2 document.querySelector('form').onsubmit = formUploader.submit

Now our application is only two lines of code and has the following benefits:

· easier for new developers to understand – they won’t get bogged down by having to read through all of the formuploader functions

· formuploader can get used in other places without duplicating code and can easily be shared on github

· the code itself is nice and simple and easy to read

There are lots of module patterns for web browser and on the server. Some of them get very complicated. The ones shown here are what I consider to be the simplest to understand.

I still don’t get it

Try reading my introduction to callbacks.

What about promises?

Promises are a more abstract pattern of working with async code in JavaScript.

The scope of this document is to show how to write vanilla javascript. If you use a third party library that adds abstraction to your JS then make sure you’re willing to force everyone that contributes to your library to also have the same views on JS as you.

In my own personal experience I use callbacks for 90% of the async code I write and when things get hairy I bring in something like the async library.

That being said, everyone develops their own unique JavaScript style and you should do what you like. Just remember that there are no absolutes: some people like to use only callbacks, some people don’t.

Additional reading

· A pattern for decoupling DOM events from @dkastner

Please contribute new sections or fix existing ones by forking this project on github!

Understanding Express.js

Original Article

http://evanhahn.com/understanding-express-js/

Evan Hahn, evanhahn.com

This is aimed at people who have some familiarity with Node.js. They know how to run Node scripts and can install packages with npm. You don’t have to be an expert, though – I promise. This guide was last updated for Express 3.2.5. It’s an introduction and mostly deals with concepts.

Express.js describes itself better than I can: “a minimal and flexible node.js web application framework”. It helps you build web apps. If you’ve used Sinatra in the Ruby world, a lot of this will be familiar.

Like any abstraction, Express hides difficult bits and says “don’t worry, you don’t need to understand this part”. It does things for you so that you don’t have to bother. In other words, it’s magic.

It’s good magic, too. Express catalogs some people using it, and there are some big names: MySpace, Klout, and even some stuff I’ve made. Me. I’m a huge deal. I’ve got a blog.

But all magic comes at a price: you might not understand the inner workings of Express. This is like driving a car; I drive a car just fine without intimate knowledge of its workings, but I’d be better off with that knowledge. What if things break? What if you want to get all the performance you can out of the car? What if you have an insatiable thirst for knowledge?

So let’s understand Express from the bottom, with Node.

Bottom layer: Node’s HTTP server

Node has an HTTP module which makes a pretty simple abstraction for making a webserver. Here’s what that might look like:

1 // Require what we need

2 var http = require("http");

3

4 // Build the server

5 var app = http.createServer(function(request, response) {

6 response.writeHead(200, {

7 "Content-Type": "text/plain"

8 });

9 response.end("Hello world!\n");

10 });

11

12 // Start that server, baby

13 app.listen(1337, "localhost");

14 console.log("Server running at http://localhost:1337/");

And if you run that app (if that file is called app.js, you’d run node app.js), you’ll get a response of “Hello world!” if you visit localhost:1337 in your browser. You’ll get the same response no matter what, too. You can try visiting localhost:1337/anime_currency or localhost:1337/?onlyfriend=anime, and it’s like talking to a brick wall: “Hello world!”

Let’s break this down a bit.

The first line uses the require function to load a built-in Node module called http. It puts this lovely module inside of a variable called http. For more about the require function, check out Nodejitsu’s docs.

Then we put a server in a variable called app by using http.createServer. This takes a function that listens for requests. We’ll get back to this in a minute because they’re Super Duper Important. Skip over it for the next two sentences.

The last thing we do is tell the server to listen for requests coming in on port 1337, and then we just log that out. And then we’re in business.

Okay, back to the request handler function. That thing is important.

The request handler

Before I start this section, I should say that there’s a bunch of cool HTTP stuff in here that I don’t think is relevant to learning Express. If you’re interested, you can look at the docs for the HTTP module because they have a bunch of stuff.

Whenever we make a request to the server, that request handler function is called. If you don’t believe me, try putting a console.log in there. You’ll see that it logs out every time you load a page.

request is a request that comes from the client. In many apps, you’ll see this shortened to req. Let’s look at it. To do that, we’ll modify the above request handler a bit:

1 var app = http.createServer(function(request, response) {

2

3 // Build the answer

4 var answer = "";

5 answer += "Request URL: " + request.url + "\n";

6 answer += "Request type: " + request.method + "\n";

7 answer += "Request headers: " + JSON.stringify(request.headers) + "\n";

8

9 // Send answer

10 response.writeHead(200, { "Content-Type": "text/plain" });

11 response.end(answer);

12

13 });

Restart the server and reload localhost:1337. You’ll see what URL you’re requesting, that it’s a GET request, and that you’ve sent a number of cool headers like the user-agent and more complicated HTTP stuff! If you visit localhost:1337/what_is_anime, you’ll see the request URL change. If you visit it with a different browser, the user-agent will change. If you send it a POST request, you’ll see the method change.

The response is the next part. Just like the prior argument is often shortened, this is often shortened to the three-letter res. With each response, you get the response all ready to send, and then you call response.end. Eventually, you must call this method; even the Node docs say so. This method does the actual sending of data. You can try making a server where you don’t call it, and it just hangs forever.

Before you send it out, you’ll want to write some headers. In our example, we do this:

1 response.writeHead(200, { "Content-Type": "text/plain" });

This does two things. First, it sends HTTP status code 200, which means “OK, everything is good”. Then, it sets some response headers. In this case, it’s saying that we’re sending back the plaintext content-type. We could send other things like JSON or HTML.

I thirst for more

You want more? Okay. You asked nicely.

One could imagine taking these APIs and turning them into something cool. You could do something (sorta) like this:

1 var http = require("http");

2

3 http.createServer(function(req, res) {

4

5 // Homepage

6 if (req.url == "/") {

7 res.writeHead(200, { "Content-Type": "text/html" });

8 res.end("Welcome to the homepage!");

9 }

10

11 // About page

12 else if (req.url == "/about") {

13 res.writeHead(200, { "Content-Type": "text/html" });

14 res.end("Welcome to the about page!");

15 }

16

17 // 404'd!

18 else {

19 res.writeHead(404, { "Content-Type": "text/plain" });

20 res.end("404 error! File not found.");

21 }

22

23 }).listen(1337, "localhost");

You could clean this up and make it pretty, or you could be hardcore like the npm.org folks and tough it out with vanilla Node. But you could also build a framework. That’s what Sencha did. And they called it Connect.

Middle layer: Connect

Fitting that Connect happens to be the middle layer of this JavaScript cake, because it calls itself “a middleware framework for node”. Don’t go searching “what is middleware” just yet – I’m about to explain it.

A little bit of Connect code

Let’s say we wanted to write the “hello world” app that we had above, but with Connect this time. Don’t forget to install Connect (npm install, baby). Once you’ve done that, the app is pretty similar.

1 // Require the stuff we need

2 var connect = require("connect");

3 var http = require("http");

4

5 // Build the app

6 var app = connect();

7

8 // Add some middleware

9 app.use(function(request, response) {

10 response.writeHead(200, { "Content-Type": "text/plain" });

11 response.end("Hello world!\n");

12 });

13

14 // Start it up!

15 http.createServer(app).listen(1337);

So let’s step through this.

First, we require Connect. We then require Node’s HTTP module just like we did before. We’re ready.

Then we make a variable called app like we did before, but instead of creating the server, we call connect(). What’s going on? What is this madness?

We then add some middleware – it’s just a function. We pass this to app.use, and this function looks an awful lot like the request handlers from above. In fact, I copy-pasted it.

Then we create the server and start listening. http.createServer took a function before, so guess what – app is just a function. It’s a Connect-made function that starts going through all the middleware until the end. But it’s just a request handler like before.

(Worth noting that you might see people using app.listen(1337), which just defers to http.createServer. This is true in both Connect and Express.)

Okay, now I’m going to explain middleware.

What is middleware?

I want to start by saying that Stephen Sugden’s description of Connect middleware is really good and does a better job than I can. If you don’t like my explanation, read his.

Remember the request handlers from a few sections earlier? Each piece of middleware is a request handler. You start by looking at the first request handler, then you look at the next one, then the next, and so on.

Here’s what middleware basically looks like:

1 function myFunMiddleware(request, response, next) {

2 // Do stuff with the request and response.

3 // When we're all done, call next() to defer to the next middleware.

4 next();

5 }

When we start a server, we start at the topmost middleware and work our way to the bottom. So if we wanted to add simple logging to our app, we could do it!

1 var connect = require("connect");

2 var http = require("http");

3 var app = connect();

4

5 // Logging middleware

6 app.use(function(request, response, next) {

7 console.log("In comes a " + request.method + " to " + request.url);

8 next();

9 });

10

11 // Send "hello world"

12 app.use(function(request, response) {

13 response.writeHead(200, { "Content-Type": "text/plain" });

14 response.end("Hello world!\n");

15 });

16

17 http.createServer(app).listen(1337);

If you run this app and visit localhost:1337, you’ll see that your server is logging some stuff and you’ll see your page.

It’s important to note that anything that works in the vanilla Node.js server also works in middleware. For example, if you want to inspect req.method, it’s right there.

While you can totally write your own, Connect comes with a bunch of cool middleware and there’s a bunch of third-party middleware too. Let’s remove our logger and use the one built into Connect:

1 var connect = require("connect");

2 var http = require("http");

3 var app = connect();

4

5 app.use(connect.logger());

6 // Fun fact: connect.logger() returns a function.

7

8 app.use(function(request, response) {

9 response.writeHead(200, { "Content-Type": "text/plain" });

10 response.end("Hello world!\n");

11 });

12

13 http.createServer(app).listen(1337);

Visit localhost:1337 and you’ll see some logging!

I thirst for more

One could imagine stringing together some middleware to build an app. Maybe you’d do it like this:

1 var connect = require("connect");

2 var http = require("http");

3 var app = connect();

4

5 app.use(connect.logger());

6

7 // Homepage

8 app.use(function(request, response, next) {

9 if (request.url == "/") {

10 response.writeHead(200, { "Content-Type": "text/plain" });

11 response.end("Welcome to the homepage!\n");

12 // The middleware stops here.

13 } else {

14 next();

15 }

16 });

17

18 // About page

19 app.use(function(request, response, next) {

20 if (request.url == "/about") {

21 response.writeHead(200, { "Content-Type": "text/plain" });

22 response.end("Welcome to the about page!\n");

23 // The middleware stops here.

24 } else {

25 next();

26 }

27 });

28

29 // 404'd!

30 app.use(function(request, response) {

31 response.writeHead(404, { "Content-Type": "text/plain" });

32 response.end("404 error!\n");

33 });

34

35 http.createServer(app).listen(1337);

“This is ugly! I need to build a framework,” you say. You savage. You’re never satisfied, are you? Will there ever be enough?

Some people saw Connect and they said, “this code can be even easier”. And so they built Expresss. (Actually, it seems like they saw Sinatra and stole it.)

Top layer: Express

We’ve finally arrived at the third act of our nerdy quest. We’re at the peak of our abstraction mountain. There is a beautiful sunset. Your long, golden locks wave in the cool breeze.

Just like Connect extends Node, Express extends Connect. The beginning looks very similar to Connect:

1 var express = require("express");

2 var http = require("http");

3 var app = express();

And so does the end:

1 http.createServer(app).listen(1337);

But the middle is what’s different. Where Connect gives you one cool feature (middleware), I think that Express gives you three cool features: routing, better request handlers, and views. Let’s start with routing.

Cool feature 1: routing

Routing is a way to map different requests to specific handlers. In many of the above examples, we had a homepage and an about page and a 404 page. We’d basically do this with a bunch of if statements in the examples.

But Express is smarter than that. Express gives us something called “routing” which I think is better explained with code than with English:

1 var express = require("express");

2 var http = require("http");

3 var app = express();

4

5 app.all("*", function(request, response, next) {

6 response.writeHead(200, { "Content-Type": "text/plain" });

7 next();

8 });

9

10 app.get("/", function(request, response) {

11 response.end("Welcome to the homepage!");

12 });

13

14 app.get("/about", function(request, response) {

15 response.end("Welcome to the about page!");

16 });

17

18 app.get("*", function(request, response) {

19 response.end("404!");

20 });

21

22 http.createServer(app).listen(1337);

Ooh. That’s hot.

After the basic requires, we say “every request goes through this function” with app.all. And that function looks an awful lot like middleware, don’t it?

The three calls to app.get are Express’s routing system. They could also be app.post, which respond to POST requests, or PUT, or any of the HTTP verbs. The first argument is a path, like /about or /. The second argument is a request handler similar to what we’ve seen before. To quote the Express documentation:

[These request handlers] behave just like middleware, with the one exception that these callbacks may invoke next('route') to bypass the remaining route callback(s). This mechanism can be used to perform pre-conditions on a route then pass control to subsequent routes when there is no reason to proceed with the route matched.

In short: they’re basically middleware like we’ve seen before. They’re just functions, just like before.

These routes can get smarter, with things like this:

1 app.get("/hello/:who", function(req, res) {

2 res.end("Hello, " + req.params.who + ".");

3 });

Restart your server and visit localhost:1337/hello/animelover69 for the following message:

Hello, animelover69.

The docs also show an example that uses regular expressions, and you can do lots of other stuff with this routing. For a conceptual understanding, I’ve said enough.

But it gets cooler.

Cool feature 2: request handling

Routing would be enough, but Express is absolutely ruthless.

Express augments the request and response objects that you’re passed in every request handler. The old stuff is still there, but they add some new stuff too! The API docs explain everything, but let’s look at a couple of examples.

One nicety they give you is a redirect method. Here are some examples:

1 response.redirect("/hello/anime");

2 response.redirect("http://www.myanimelist.net");

3 response.redirect(301, "http://www.anime.org"); // HTTP status code 301

This isn’t in vanilla Node and it’s also absent from Connect, but Express adds this stuff. It adds things like sendFile which lets you just send a whole file:

1 response.sendFile("/path/to/anime.mp4");

The request gets a number of cool properties, like request.ip to get the IP address and request.files to get uploaded files.

Conceptually, there’s not much to know, other than the fact that Express extends the request and response. For everything Express gives you, check out the API docs.

Cool feature 3: views

More features? Oh, Express, I’m blushing.

Express can handle views. It’s not too bad. Here’s what the setup looks like:

1 // Start Express

2 var express = require("express");

3 var app = express();

4

5 // Set the view directory to /views

6 app.set("views", __dirname + "/views");

7

8 // Let's use the Jade templating language

9 app.set("view engine", "jade");

The first block is the same as always. Then we say “our views are in a folder called ‘views’”. Then we say “use Jade”. Jade is a templating language. We’ll see how it works in just a second!

Now, we’ve set up these views. How do we use them?

Let’s start by making a file called index.jade and put it into a directory called views. It might look like this:

1 doctype 5

2 html

3 body

4 h1 Hello, world!

5 p= message

This is basically HTML without all the brackets. It should be fairly straightforward if you know HTML. The only interesting part is the last line. message is a variable! Woah! Where did that come from? I’ll tell you.

We need to render the view from within Express. Here’s what that looks like:

1 app.get("/", function(request, response) {

2 response.render("index", { message: "I love anime" });

3 });

Express adds a method to response, called render. It does a bunch of smart stuff, but it basically looks at the view engine and views directory (the stuff we defined earlier) and renders index.jade.

The last step (I suppose it could be the first step) is to install Jade, because it’s not bundled with Express. Add it to your package.json or npm install it.

If you get all of this set up, you’ll see this page. Here’s all the source code.

Bonus cool feature: everything from Connect and Node

I want to remind you that Express is built on top of Connect which is built on top of Node. This means that all Connect middleware works with Express. This is useful! For example:

1 var express = require("express");

2 var app = express();

3

4 app.use(express.logger()); // Inherited from Connect

5

6 app.get("/", function(req, res) {

7 res.send("anime");

8 });

9

10 app.listen(1337);

If you learn one thing from this post, it should be this. If your brain has room for another fun fact: hippo milk is pink!

Actually building something

Most of the stuff in this post is conceptual, but let me push you in the right direction for building something you want to build. I don’t want to delve into specifics.

You can install Express as an executable in your terminal. It spits out boilerplate code that’s very helpful for starting your app. Install it globally with npm:

1 ### You'll probably need `sudo` for this:

2 npm install -g express

If you need help, use express --help. It spits out some options. For example, let’s say I want to use EJS templating and LESS for CSS. My app is called “myApp”. Here’s what I’d type to get started:

1 express --ejs --css less myApp

It’ll generate a bunch of files and then tell you to go into that directory and npm install. If you do that, you’ll have a basic app running with node app! I’d recommend looking through the generated files to see some boilerplate, and then messing with it a bunch. It’s hardly a full app, but I found it very helpful to poke through these files and mess with them when getting started.

Also helpful are the many official examples on GitHub.

Some concluding miscellany

· If you love CoffeeScript like I do, you should know that all of this stuff works with CoffeeScript. You don’t even need to compile it! Instead of starting your server with node app.js, start it with coffee app.coffee. This is what I do in my apps. Me. I’m a big deal. I’ve got a blog.

· I was confused when I saw app.use(app.router) – doesn’t Express always use a router? The short answer is that app.router is Express’s routing middleware, and it’s implicitly included when you define a route. You can explicitly include it because you want the router middleware to come before other stuff, which is sometimes desirable. This StackOverflow answer explains it well.

· This guide was written for Express 3, and the version 4 roadmap shows the possibility of some dramatic changes. Most notably, it looks like Express might be split up into a bunch of small modules and eat some of Connect’s features. It’s up in the air, but the “plans” are worth a look.

I thirst for more

Is there no satisfying you? You glutton. You make me sick. Soon you’re gonna be sitting in an opium den, eyes half-open, drooling out the last drop of your programming talent.

Just like Rails is the de-facto way to build web apps with Ruby and demonic masochism is the de-facto way to build web apps in PHP, I get the impression that Express is the de-facto way to build web apps in Node. But unlike Rails, Express is much lower-level. It seems like no high-level Node library has stuck out. I think this is going to change. Keep your eyes out.

I won’t go into them here, but just as Express was built on Connect and Connect on Node, people have built things on top of Express. The Express wiki lists them and many of them are Pretty Cool. You can use these frameworks if you’d prefer, or you can stick to the lower-level Express. Either way, go build cool stuff!

Previous: Concept: making asynchronous loading look synchronous

Dear fellow copyright nerd: all content licensed under the Creative Commons Attribution License unless noted otherwise. All code is free-license under the Unlicense unless noted otherwise. The logo was drawn by the lovely Lulu Tang. You look absolutely ravishing. Please come back soon.