Creating An HTTPS Server

To initialize a express.HTTPSServer we do the same as above, however we
pass an options object, accepting key, cert and the others mentioned in node’s https documentation.

var app = require('express').createServer({ key: ... });

Configuration

Express supports arbitrary environments, such as production and development. Developers
can use the configure() method to setup needs required by the current environment. When
configure() is called without an environment name it will be run in every environment
prior to the environment specific callback.

In the example below we only dumpExceptions, and respond with exception stack traces
in development mode, however for both environments we utilize methodOverride and bodyParser.
Note the use of app.router, which can (optionally) be used to mount the application routes,
otherwise the first call to app.get(), app.post(), etc will mount the routes.

Routing

Express utilizes the HTTP verbs to provide a meaningful, expressive routing API.
For example we may want to render a user’s account for the path /user/12, this
can be done by defining the route below. The values associated to the named placeholders
are available as req.params.

A route is simple a string which is compiled to a RegExp internally. For example
when /user/:id is compiled, a simplified version of the regexp may look similar to:

\/user\/([^\/]+)\/?

Regular expression literals may also be passed for complex uses. Since capture
groups with literal RegExp’s are anonymous we can access them directly req.params. So our first capture group would be req.params[0] and the second would follow as req.params[1].

Typically we may use a “dumb” placeholder such as “/user/:id” which has no restrictions, however say for example we are limiting a user id to digits, we may use ‘/user/:id([0-9]+)’ which will not match unless the placeholder value contains only digits.

Passing Route Control

We may pass control to the next matching route, by calling the third argument,
the next() function. When a match cannot be made, control is passed back to Connect,
and middleware continue to be invoked in the order that they are added via use(). The same is true for several routes which have the same path defined, they will simply be executed in order until one does not call next() and decides to respond.

This is somewhat annoying, so express re-exports these middleware properties, however they are identical:

app.use(express.logger());
app.use(express.bodyParser());

Middleware ordering is important, when Connect receives a request the first middleware we pass to createServer() or use() is executed with three parameters, request, response, and a callback function usually named next. When next() is invoked the second middleware will then have it’s turn and so on. This is important to note because many middleware depend on each other, for example methodOverride() checks req.body.method for the HTTP method override, however bodyParser() parses the request body and populates req.body. Another example of this is cookie parsing and session support, we must first use()cookieParser() followed by session()_.

Many Express applications may contain the line app.use(app.router), while this may appear strange, it’s simply the middleware function that contains all defined routes, and performs route lookup based on the current request url and HTTP method. Express allows you to position this middleware, though by default it will be added to the bottom. By positioning the router, we can alter middleware precedence, for example we may want to add error reporting as the last middleware so that any exception passed to next() will be handled by it, or perhaps we want static file serving to have low precedence, allowing our routes to intercept requests to a static file to count downloads etc. This may look a little like below

First we add logger() so that it may wrap node’s req.end() method, providing us with response-time data. Next the request’s body will be parsed (if any), followed by cookie parsing and session support, meaning req.session will be defined by the time we hit our routes in app.router. If a request such as GET /javascripts/jquery.js is handled by our routes, and we do not call next() then the static() middleware will never see this request, however if were to define a route as shown below, we can record stats, refuse downloads, consume download credits etc.

Route Middleware

Routes may utilize route-specific middleware by passing one or more additional callbacks (or arrays) to the method. This feature is extremely useful for restricting access, loading data used by the route etc.

Typically async data retrieval might look similar to below, where we take the :id parameter, and attempt loading a user.

To keep things DRY and to increase readability we can apply this logic within a middleware. As you can see below, abstracting this logic into middleware allows us to reuse it, and clean up our route at the same time.

Multiple route middleware can be applied, and will be executed sequentially to apply further logic such as restricting access to a user account. In the example below only the authenticated user may edit his/her account.

There are times when we may want to “skip” passed remaining route middleware, but continue matching subsequent routes. To do this we invoke next() with the string “route” next('route'). If no remaining routes match the request url then Express will respond with 404 Not Found.

HTTP Methods

We have seen app.get() a few times, however Express also exposes other familiar HTTP verbs in the same manor, such as app.post(), app.del(), etc.

A common example for POST usage, is when “submitting” a form. Below we simply set our form method to “post” in our html, and control will be given to the route we have defined below it.

By default Express does not know what to do with this request body, so we should add the bodyParser middleware, which will parse application/x-www-form-urlencoded and application/json request bodies and place the variables in req.body. We can do this by “using” the middleware as shown below:

app.use(express.bodyParser());

Our route below will now have access to the req.body.user object which will contain the name and email properties when defined.

When using methods such as PUT with a form, we can utilize a hidden input named _method, which can be used to alter the HTTP method. To do so we first need the methodOverride middleware, which should be placed below bodyParser so that it can utilize it’s req.body containing the form values.

app.use(express.bodyParser());
app.use(express.methodOverride());

The reason that these are not always defaults, is simply because these are not required for Express to be fully functional. Depending on the needs of your application, you may not need these at all, your methods such as PUT and DELETE can still be accessed by clients which can use them directly, although methodOverride provides a great solution for forms. Below shows what the usage of PUT might look like:

Error Handling

Express provides the app.error() method which receives exceptions thrown within a route,
or passed to next(err). Below is an example which serves different pages based on our
ad-hoc NotFound exception:

We can call app.error() several times as shown below.
Here we check for an instanceof NotFound and show the
404 page, or we pass on to the next error handler.

Note that these handlers can be defined anywhere, as they
will be placed below the route handlers on listen(). This
allows for definition within configure() blocks so we can
handle exceptions in different ways based on the environment.

Here we assume all errors as 500 for the simplicity of
this demo, however you can choose whatever you like. For example when node performs filesystem syscalls, you may receive an error object with the error.code of ENOENT, meaning “no such file or directory”, we can utilize this in our error handling and display a page specific to this if desired.

The errorHandler middleware also responds with json if Accept: application/json
is present, which is useful for developing apps that rely heavily on client-side JavaScript.

Route Param Pre-conditions

Route param pre-conditions can drastically improve the readability of your application, through implicit loading of data, and validation of request urls. For example if you are constantly fetching common data for several routes, such as loading a user for /user/:id, we might typically do something like below:

With preconditions our params can be mapped to callbacks which may perform validation, coercion, or even loading data from a database. Below we invoke app.param() with the parameter name we wish to map to some middleware, as you can see we receive the id argument which contains the placeholder value. Using this we load the user and perform error handling as usual, and simple call next() to pass control to the next precondition or route handler.

View Rendering

View filenames take the form “<name>.<engine>”, where <engine> is the name
of the module that will be required. For example the view layout.ejs will
tell the view system to require(‘ejs’), the module being loaded must export the method exports.compile(str, options), and return a Function to comply with Express. To alter this behaviour
app.register() can be used to map engines to file extensions, so that for example “foo.html” can be rendered by ejs.

Below is an example using Jade to render index.html,
and since we do not use layout: false the rendered contents of index.jade will be passed as
the body local variable in layout.jade.

The new view engine setting allows us to specify our default template engine,
so for example when using jade we could set:

app.set('view engine', 'jade');

Allowing us to render with:

res.render('index');

vs:

res.render('index.jade');

When view engine is set, extensions are entirely optional, however we can still
mix and match template engines:

res.render('another-page.ejs');

Express also provides the view options setting, which is applied each time a view is rendered, so for example if you rarely use layouts you may set:

app.set('view options', {
layout: false
});

Which can then be overridden within the res.render() call if need be:

res.render('myview.ejs', { layout: true });

When an alternate layout is required, we may also specify a path. For example if we have view engine set to jade and a file named ./views/mylayout.jade we can simply pass:

res.render('page', { layout: 'mylayout' });

Otherwise we must specify the extension:

res.render('page', { layout: 'mylayout.jade' });

These paths may also be absolute:

res.render('page', { layout: __dirname + '/../../mylayout.jade' });

A good example of this is specifying custom ejs opening and closing tags:

app.set('view options', {
open: '{{',
close: '}}'
});

View Partials

The Express view system has built-in support for partials and collections, which are “mini” views representing a document fragment. For example rather than iterating
in a view to display comments, we could use partial collection:

partial('comment', { collection: comments });

If no other options or local variables are desired, we can omit the object and simply pass our array, which is equivalent to above:

partial('comment', comments);

When using the partial collection support a few “magic” locals are provided
for free:

firstInCollection true if this is the first object

indexInCollection index of the object in the collection

lastInCollection true if this is the last object

collectionLength length of the collection

Local variables passed (or generated) take precedence, however locals passed to the parent view are available in the child view as well. So for example if we were to render a blog post with partial(‘blog/post’, post) it would generate the post local, but the view calling this function had the local user, it would be available to the blog/post view as well.

NOTE: be careful about when you use partial collections, as rendering an array with a length of 100 means we have to render 100 views. For simple collections you may inline the iteration instead of using partial collection support to decrease overhead.

View Lookup

View lookup is performed relative to the parent view, for example if we had a page view named views/user/list.jade, and within that view we did partial(‘edit’) it would attempt to load views/user/edit.jade, whereas partial(‘../messages’) would load views/messages.jade.

The view system also allows for index templates, allowing you to have a directory of the same name. For example within a route we may have res.render(‘users’) either views/users.jade, or views/users/index.jade.

When utilizing index views as shown above, we may reference views/users/index.jade from a view in the same directory by partial(‘users’), and the view system will try ../users/index, preventing us from needing to call partial(‘index’).

By default the session middleware uses the memory store bundled with Connect, however many implementations exist. For example connect-redis supplies a Redis session store and can be used as shown below:

Now the req.session and req.sessionStore properties will be accessible to all routes and subsequent middleware. Properties on req.session are automatically saved on a response, so for example if we wish to shopping cart data:

The req.session object also has methods such as Session#touch(), Session#destroy(), Session#regenerate() among others to maintain and manipulate sessions. For more information view the Connect Session documentation.

Migration Guide

Express 1.x developers may reference the Migration Guide to get up to speed on how to upgrade your application to work with Express 2.x, Connect 1.x, and Node 0.4.x.

req.header(key[, defaultValue])

Get the case-insensitive request header key, with optional defaultValue:

req.header('Host');
req.header('host');
req.header('Accept', '*/*');

The Referrer and Referer header fields are special-cased, either will work:

req.accepts(type)

Check if the Accept header is present, and includes the given type.

When the Accept header is not present true is returned. Otherwise
the given type is matched by an exact match, and then subtypes. You
may pass the subtype such as “html” which is then converted internally
to “text/html” using the mime lookup table.

Ad-hoc callbacks can also be registered with Express, to perform
assertions again the request, for example if we need an expressive
way to check if our incoming request is an image, we can register “an image”
callback:

res.attachment([filename])

Sets the Content-Disposition response header to “attachment”, with optional filename.

res.attachment('path/to/my/image.png');

res.sendfile(path[, options[, callback]])

Used by res.download() to transfer an arbitrary file.

res.sendfile('path/to/my.file');

This method accepts an optional callback which is called when
an error occurs, or when the transfer is complete. By default failures call next(err), however when a callback is supplied you must do this explicitly, or act on the error.

res.send(body|status[, headers|status[, status]])

The res.send() method is a high level response utility allowing you to pass
objects to respond with json, strings for html, Buffer instances, or numbers representing the status code. The following are all valid uses:

By default the Content-Type response header is set, however if explicitly
assigned through res.send() or previously with res.header() or res.contentType()
it will not be set again.

Note that this method end()s the response, so you will want to use node’s res.write() for multiple writes or streaming.

res.json(obj[, headers|status[, status]])

Send a JSON response with optional headers and status. This method
is ideal for JSON-only APIs, however res.send(obj) will send JSON as
well, though not ideal for cases when you want to send for example a string
as JSON, since the default for res.send(string) is text/html.

This options object is also considered an “options” object. For example
when you pass the status local, it’s not only available to the view, it
sets the response status to this number. This is also useful if a template
engine accepts specific options, such as debug, or compress. Below
is an example of how one might render an error page, passing the status for
display, as well as it setting res.statusCode.

The exception of this, is when a “plain” object, aka “{}” or “new Object” is passed, which is considered an object with local variable. For example some may expect a “movie” local with the following, however since it is a plain object “director” and “title” are simply locals:

When mounted, res.redirect() will respect the mount-point. For example if a blog app is mounted at /blog, the following will redirect to /blog/posts:

res.redirect('/posts');

app.error(function)

Adds an error handler function which will receive the exception as the first parameter as shown below.
Note that we may set several error handlers by making several calls to this method, however the handler
should call next(err) if it does not wish to deal with the exception:

app.helpers(obj)

Our view could now utilize the firstName and lastName variables,
as well as the name() function exposed.

<%= name(firstName, lastName) %>

Express also provides a few locals by default:

- `settings` the app's settings object
- `layout(path)` specify the layout from within a view

This method is aliased as app.locals().

app.dynamicHelpers(obj)

Registers dynamic view helpers. Dynamic view helpers
are simply functions which accept req, res, and are
evaluated against the Server instance before a view is rendered. The return value of this function
becomes the local variable it is associated with.

app.match

The app.match http methods return an array of callback functions
which match the given url, which may include a query string etc. This
is useful when you want reflect on which routes have the opportunity to
respond.

app.register(ext, exports)

Register the given template engine exports
as ext. For example we may wish to map “.html”
files to jade:

app.register('.html', require('jade'));

This is also useful for libraries that may not
match extensions correctly. For example my haml.js
library is installed from npm as “hamljs” so instead
of layout.hamljs, we can register the engine as “.haml”:

app.register('.haml', require('haml-js'));

For engines that do not comply with the Express
specification, we can also wrap their api this way. Below
we map .md to render markdown files, rendering the html once
since it will not change on subsequent calls, and support local substitution
in the form of “{name}”.