Now that we understand some of how to work with databases, let’s consider how they map to our efforts in web development. Consider our equipment list program - what kinds of things will we do with the equipment list?

Most likely, we’ll want to see what is on the list, add new equipment to the list, update equipment on the list, and remove equipment.


It turns out that these actions: Create, Read, Update, and Destroy, are so common in web programming that they have an acronym: CRUD. Quite plainly, they map to SQL commands:

Create maps to:

INSERT INTO tablename (col1, col2, ...) VALUES (val1, val2, ...);

Read maps to:

SELECT * FROM tablename;

for all records, or

SELECT * FROM tablename WHERE id = id_value;

for a specific record (where ID is typically the primary key).

Update maps to:

UPDATE tablename SET col1=val1, col2=val2, ... WHERE ID = id_value;

And Destroy maps to:

DELETE FROM tablename WHERE id = id_value

Representational State Transfer

While CRUD embodies the actions we want to take in reference to particular resources our web app is providing (like our equipment in the equipment list), we still need a way to map those calls to a web application. One particularly powerful architecture for doing so is Representational State Transfer, aka REST. REST was developed by Roy Thomas Fielding as his PhD research, and maps pairs of URIs with HTTP verbs (GET, POST, PUT, DELETE) to particular CRUD actions. RESTful routes are typically:

/path/to/resource GET Read (all)
/path/to/resource/id GET Read (resource with id)
/path/to/resource POST Create
/path/to/resource/id PUT or PATCH Update (resource with id)
/path/to/resource/id DELETE Destroy (resource with id)

GOTCHA: The PUT verb indicates that the request contains the full, modified version of the resource that needs to be updated. In contrast, PATCH contains the instructions on how to change it, though they have been used interchangeably in some web frameworks.

Implementing Rest in Node

How do we implement a RESTful architecture in Node? Up to this point, we’ve been using either a series of if statements or a switch statement to map incoming requests to response handling functions - but it was getting messy once we had to worry about both URIs and HTTP Verbs, but now we also need to potentially parse out an id value as well. It may be time to wrap this functionality within an abstraction - and object that can map the incoming request to a specific function. In web development, we call this object a router.

The router maintains a list of path-to-function mappings, and becomes the first stage in our request handling - it receives the request, matches it’s logical path to the appropriate function, and then invokes that function, passing on the request. It also typically parses out the id value (if there is one) and provides it to the function as well, and in some frameworks it may also parse the query string and any form data. But how can we make it match a path when the path may contain an ID or other non-static value?

The If/Else and Switch statements we have used previously don’t provide an easy approach for this. String operations could be used... but Regular Expressions are a natural fit for the problem.

Regular Expressions

The answer is with Regular Expressions (or regexp), a tool from formal language theory that has become commonplace in web programming (as well as the basis of the linux grep utility). A regexp is a series of characters that define a pattern in text, like /ab+c/ which corresponds to a string containing the character a, followed by one or more character b’s, and then a character c. Thus, the strings abc, abbc, abbbc, and fabcy would all be matches, whereas the strings ac, fab, and bccy would not.

Some characters have special meanings, like + (one or more of the preceding expression), * (zero or more matches of the preceding expression), ? (matches the preceding expression zero or one times), ^ (the start of input), $ (the end of input), . (any single character). Further, square brackets ([]) define a set - any character in the set will match, i.e. [abc] will match an a, b, or c. Also, some characters prefaced with a backslash (\) have a special meaning, like \s (any whitespace character), \S (any non-whitespace character), \w (any alphanumeric character including underscore), \W (any non-word character). A far more detailed list of RegExp characters and expressions can be found on the Mozilla Developer Network [here] (, and an interactive JavaScript regular expression prototyper can be found at

Finally, expressions within parentheses are capture groups, which can be recalled for later use - this is how we would want to capture our id value. So a regular expression for one of our routes might be:

var route = /\/resources\/(\d+)\w*/

Note the need to escape the forward slash (/), which in JavaScript defines the start / end of a regular expression, much like single or double quotes denote a string. We also optionally capture a multi-digit number with (\d*) that could be followed by more alphanumeric characters - a common pattern in some web frameworks is to make resources more human-friendly by appending a name to the id, i.e. https://localhost/equipment/1-WiiMotes. By capturing the number and ignoring the name, we keep the human-readability without incurring the cost of comparing strings.

In JavaScript, regular expressions are first-order objects - we can pass them, store them in variables and arrays, and even compare them. However, comparing a regular expression with a string we want to test against it will never be true. Instead, we need to use the String.prototype.match(regexp) or RegExp.prototype.exec() functions (or their siblings). Both of these return null for no match, or an array containing the matched text at index 0, and any capture groups starting at index 1.

Thus, we can store our route regex and corresponding functions in a map-like structure: for example, an array of simple objects {regexp: RexExp, callback: function}, and check routes for matches one at a time:

function Router() { this.routemap = [ {/\/equipment\/(d+)\w*/, show], // read for a single equipment item [/\/eqiupment\/\/?/, index] // read for all equipment items ] } Router.prototype.route = function(req, res) { var resource = req.url.split(“?”)[0]; for(var i = 0; i < this.routemap.length; i++) { var match = this.routemap[i].regexp.exec(resource); if(match != null) { return this.routemap[i].callback(req, res, match.slice(1)); } } }

In the above code, when we find a match we trigger its callback, which we assume to take the request, response, and an array of matching values in order of their match.

Using Tokens in a Match

While this is a powerful approach, it does require the programmer to keep track of the order that capture groups appear. Most web frameworks go a step farther and employ a key/value approach to capture groups. This also means they need to specify what the key is, so they typically wrap their definition of routes in a second layer of abstraction - instead of defining them in terms of a regular expression, they use a string with special tokens, i.e.


Where any string preceded by a colon is a capture token - which should be used as a key for the capture group. When we add routes to our router using this approach, we must first convert the provided route into a regular expression, and keep track of our tokens.

Router.prototype.addRoute = function(route, callback) { var tokens = route.split("/"), exp = [], keys = []; console.log(this); // Convert route pattern to a RegExp for(var i = 0; i < tokens.length; i++) { var match = tokens[i].match(/:(\w+)/); if(match) { // found a key - create a capture group exp.push("([^\/])"); keys.push(match[1]); } else { // otherwise, push token as-is exp.push(tokens[i]); } } regexp = new RegExp('^' + exp.join('/') + '/?$'); // Add to our routemap this.routemap.push({ regexp: regexp, keys: keys, callback: callback }); }

With the keys now a part of our routemap, we need to apply them in our route handler:

Router.prototype.route = function(request, response) { var path = request.url.split('?')[0]; // The node http Server applies a custom scope // to request handlers, so we explicitly must // make our routemap available this.routemap = exports.routemap; for(var i = 0; i < this.routemap.length; i++) { console.log(this.routemap[i].regexp, path); var match = this.routemap[i].regexp.exec(path); console.log(match); if(match) { // found a matching route! // store our parameters as a key/value map var params = {}; for(var j = 0; j < this.routemap[i].keys.length; j++) { params[this.routemap[i].keys[j]] = match[j+1]; } // trigger the callback function and surrender control return this.routemap[0].callback(request, response, params); } } // If we get here, there was no match! response.writeHead(404, {'Content-Type':'text/html'}); response.end("<h1>Resource Not Found</h1>"); }

When a match is found, we now assign its capture groups to the keys in order, and supply the entire key/value mapping to the callback function as a third argument. alternatively, we could use call() or apply() to set this mapping as the scope of the called object - but we actually are already doing this to pass on the this scope, which (you may be surprised to learn) is not going to be the router object itself. This is because the Node http.Server overrides the context of the request handler passed to it, in order to prove rich contextual data about the server in the this scope instead.

To preserve our object's scope, we can wrap the router.route call in an anonymous function:

new http.Server(function(req, res){ router.route(req, res); });

Using the Module Pattern

You probably noticed that our examples have been getting longer - and when a code file gets long, our response is to break it into multiple files. In Node, this is typically done with modules. In fact, you’ve already been using them - anything we include with a require() function is a module. But in this case, we want to create a user-defined module. It is actually pretty straightforward - we just need to assign a value to an exports variable, and when Node processes the require() call it will attach that value to what attaches to. So to make our router into a module, we need to add:

module.exports = exports = new Router();

To our file. To use the module in another file, we simply need to require it with a file path, i.e.:

var router = require(‘./router’);

HTTP Verbs

So far, we’ve only worried about parsing the url and turning it into a function call. But what about the second mechanism of RESTful routes - the http verb?

One straightforward approach is that, rather than having a single route map, we have one for each verb. This requires a bit of tweaking to our router constructor:

function Router() { this.routemap = { 'get': [], 'put': [], 'post': [], 'delete': [] }; }

In our addRoute() function, we need to add a verb to the parameters, and use it when we populate the routemap:

Router.prototype.addRoute = function(route, verb, callback) { ... // push the route to our this.routemap this.routemap[verb.toLowerCase()].push({ regexp: regexp, keys: keys, callback: callback }); }

And finally, because we’re already assigning the routemap to a local variable in our route() function, that’s all we’ll need to tweak there:

var routemap = exports.routemap[request.method.toLowerCase()];

RESTful Resources

Ideally, since RESTful routes will likely be common in our web application, we’d like to be able to tell the router about a resource, and have it set up all the routes for us instead of having to create them each by hand. This can be another function - createResource() that would need to know the name of the resource, and the functions corresponding to each CRUD action - which, we could decide by convention to be create(), show(), index(), update(), and delete(). Moreover, many RESTful apps add two additional routes: “path/to/resource/new” and “path/to/resource/:id/edit” to display forms corresponding to the create and edit actions. Thus, we would have a function like:

Router.prototype.addResource = function(resource, controller) { // add create this.addRoute('/' + resource, 'post', controller.create); this.addRoute('/' + resource + '/new', 'get',; // and read this.addRoute('/' + resource + '/:id', 'get',; this.addRoute('/' + resource, 'get', controller.index); // add update this.addRoute('/' + resource + '/:id', 'put', controller.update); this.addRoute('/' + resource + '/:id/edit', 'get', controller.edit); // add delete this.addRoute('/' + resource, 'delete', controller.destroy); }

CRUD Functions for the Equipment Server

To wrap up, we need to supply an object with the corresponding CRUD action functions to our router. Let’s define those now.

var controller = {}

Read Actions

Let’s start with read, as it is probably the most familiar to us at this point:

controller.index = function(req, res, params) { db.all('SELECT * FROM equipment', function(err, rows) { if(err) return console.error(err); render(req, res, rows) }); }

The db.all() method is similar to the db.each() method we used earlier, except it grabs all the rows at once, rather than one-at-a-time. If our database isn’t too large, this will generally be preferred. However, for very large tables, this consumes a lot of memory, so in those cases handling it one-row-at-a-time may be preferable.

And for our render() function, we would concatenate strings as we have previously to build a page with each of the items in the equipment database listed:

function render(req, res,rows) { var list = "<ul>"; list += function(row){ return "<li>" + + "[" + row.serial + "]</li>"; }).join(""); list += "</ul>"; var page = "<!doctype><html>" + "<head><title>Equipment</title></head>" + "<body><h1>Equipment</h1>" + list + "</body></html>"; res.writeHead(200, {“Content-Type”:”text/html”}); res.end(page); }

Create Action

The Create function needs to read from a form - we’ll use the formidable library to simplify this for us. It supplies an object - IncomingForm - which receives and parses the form data (and attached files, for multipart forms). This is then exposed in a callback, keeping the form downloading asynchronous.

controller.create = function(req, res, params) { var form = new formidable.IncomingForm(); form.parse(req, function(err, fields, files) { if(err) return console.error(err);"INSERT INTO equipment (name, serial) VALUES (?,?);",, fields.serial, function() {controller.index(req, res);} ); }); }

After we’ve inserted the new object into the database, we call the controller.index() function, which renders and responds with the list of all equipment. We’ll also need a form to collect the data - we can either generate that from a function or load it from a file.

<!-- form.html --> <form action="/equipment/" method="POST"> <label for="name"> <input name="name" type="text" /> </label> <label for="serial" type="text"> <input name="serial" type="text" /> </label> <input type="submit" value="Save" /> </form>

This is enough to get our server up and running, but we still have more CRUD/REST function/route mappings to accomplish, and we’ll probably want more than a one-page application.