Express and Node.js Training from StrongLoop

4.x API

Application

express()

Create an express application.

var express = require('express');
var app = express();

app.get('/', function(req, res){
  res.send('hello world');
});

app.listen(3000);

settings

Express application settings can be set using app.set(), and retrieved using app.get(). The following settings will alter how the app behaves:

  • trust proxy Indicate that the app is sitting behind a front-facing proxy, and the X-Forwarded-* headers may be trusted for determining the connection and the IP address of the client. It must, however, be noted that, the X-Forwarded-* headers are easily spoofed and the detected IP addresses are unreliable.

    trust proxy is disabled by default. When enabled, Express attempts to determine the IP address of the client which is connected through the front-facing proxy, or a series of proxies. The req.ips property, then, contains an array of IP addresses the client is connected through. It can be enabled using either of the following values.

    TypeValue
    Boolean If true, the client's IP address is understood as the left-most entry in the X-Forwarded-* header.
    If false, the app is understood as directly facing the Internet and the client's IP address is derived from req.connection.remoteAddress. This is the default setting.
    IP addresses An IP address, subnet, or an array of IP addresses, and subnets to trust. The following is the list of pre-configured subnet names.
    • loopback - 127.0.0.1/8, ::1/128
    • linklocal - 169.254.0.0/16, fe80::/10
    • uniquelocal - 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, fc00::/7
    The IP addresses can be set in the following ways.
    app.set('trust proxy', 'loopback') // specify a single subnet
    app.set('trust proxy', 'loopback, 123.123.123.123') // specify a subnet and an address
    app.set('trust proxy', 'loopback, linklocal, uniquelocal') // specify multiple subnets as CSV
    app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']) // specify multiple subnets as an array
    When specified, the IP addresses or the subnets are excluded from the address determination process, and the untrusted IP address nearest to the application server is determined as the client's IP address.
    Number Trust the nth hop from the front-facing proxy server as the client.
    Function Custom trust implementation. Use this only if you know what you are doing.
    app.set('trust proxy', function (ip) {
      if (ip === '127.0.0.1' || ip === '123.123.123.123') return true; // trusted IPs
      else return false;
    })

    The trust proxy setting is implemented using the proxy-addr package, look up its documentation for further details.

  • env Environment mode, defaults to process.env.NODE_ENV (NODE_ENV environment variable) or "development".
  • subdomain offset The number of dot-separated parts of the host to remove to access subdomain, two by default.
  • jsonp callback name Changes the default callback name of ?callback=.
  • json replacer JSON replacer callback, null by default.
  • json spaces When set, sends prettified JSON string indented with the specified amount of spaces. Disabled by default.
  • case sensitive routing Enable case sensitivity, disabled by default, treating "/Foo" and "/foo" as the same.
  • strict routing Enable strict routing, by default "/foo" and "/foo/" are treated the same by the router.
  • view cache Enables view template compilation caching, enabled in production by default.
  • view engine The default engine extension to use when omitted.
  • views The view directory path, defaulting to "process.cwd() + '/views'".
  • query parser The query parser to use - "simple" or "extended", defaults to "extended". The simple query parser is based on node's native query parser, querystring. The extended query parser is based on qs.
  • x-powered-by Enables the "X-Powered-By: Express" HTTP header, enabled by default.
  • etag Set the ETag response header.

    TypeValue
    Boolean true enables strong ETag. This is the default setting.
    false disables ETag altogether.
    String If "strong", enables strong ETag.
    If "weak", enables weak ETag.
    Function Custom ETag function implementation. Use this only if you know what you are doing.
    app.set('etag', function (body, encoding) {
      return generateHash(body, encoding); // consider the function is defined
    })

    More about the HTTP ETag header.

app.set(name, value)

Assigns setting name to value.

app.set('title', 'My Site');
app.get('title'); // "My Site"

app.get(name)

Get setting name value.

app.get('title');
// => undefined

app.set('title', 'My Site');
app.get('title');
// => "My Site"

app.enable(name)

Set setting name to true.

app.enable('trust proxy');
app.get('trust proxy');
// => true

app.enabled(name)

Check if setting name is enabled.

app.enabled('trust proxy');
// => false

app.enable('trust proxy');
app.enabled('trust proxy');
// => true

app.disable(name)

Set setting name to false.

app.disable('trust proxy');
app.get('trust proxy');
// => false

app.disabled(name)

Check if setting name is disabled.

app.disabled('trust proxy');
// => true

app.enable('trust proxy');
app.disabled('trust proxy');
// => false

app.use([path], [function...], function)

Mount the middleware function(s) at the path. If path is not specified, it defaults to "/".

Mounting a middleware at a path will cause the middleware function to be executed whenever the base of the requested path matches the path.

Since path defaults to "/", middleware mounted without a path will be executed for every request to the app.

// this middleware will be executed for every request to the app
app.use(function (req, res, next) {
  console.log('Time: %d', Date.now());
  next();
})

Middleware functions are executed sequentially, therefore the order of middleware inclusion is important.

// this middleware will not allow the request to go beyond it
app.use(function(req, res, next) {
  res.send('Hello World');
})

// requests will never reach this route
app.get('/', function (req, res) {
  res.send('Welcome');
})

path can be a string representing a path, a path pattern, a regular expression to match paths, or an array of combinations of the aforementioned path objects.

The middleware examples below are intentionally left overly simple to keep the examples lean and clutter-free.
Type Example
Path
// will match paths starting with /abcd
app.use('/abcd', function (req, res, next) {
  next();
})
Path Pattern
// will match paths starting with /abcd and /abd
app.use('/abc?d', function (req, res, next) {
  next();
})

// will match paths starting with /abcd, /abbcd, /abbbbbcd and so on
app.use('/ab+cd', function (req, res, next) {
  next();
})

// will match paths starting with /abcd, /abxcd, /abFOOcd, /abbArcd and so on
app.use('/ab*cd', function (req, res, next) {
  next();
})

// will match paths starting with /ad and /abcd
app.use('/a(bc)?d', function (req, res, next) {
  next();
})
Regular Expression
// will match paths starting with /abc and /xyz
app.use(/\/abc|\/xyz/, function (req, res, next) {
  next();
})
Array
// will match paths starting with /abcd, /xyza, /lmn, and /pqr
app.use(['/abcd', '/xyza', /\/lmn|\/pqr/], function (req, res, next) {
  next();
})

function can be a middleware function, a series of middleware functions, an array of middleware functions, or a combination of all of them. Since routers and apps implement the middleware interface, they can be used like any other middleware function.

Usage Example
Single Middleware A middleware function can be defined and mounted locally.
app.use(function (req, res, next) {
  next();
})
A router is a valid middleware.
var router = express.Router();
router.get('/', function (req, res, next) {
  next();
})
app.use(router);
An Express app is a valid middleware.
var subApp = express();
subApp.get('/', function (req, res, next) {
  next();
})
app.use(subApp);
Series of Middleware More than one middleware can be specified at a mount path.
var r1 = express.Router();
r1.get('/', function (req, res, next) {
  next();
})

var r2 = express.Router();
r2.get('/', function (req, res, next) {
  next();
})

app.use(r1, r2);
Array Clubbing middleware in arrays is a good way to logically group them. The mount path has to be specified, if an array of middleware is passed as the first or the only set of middleware.
var r1 = express.Router();
r1.get('/', function (req, res, next) {
  next();
})

var r2 = express.Router();
r2.get('/', function (req, res, next) {
  next();
})

app.use('/', [r1, r2]);
Combination All the above ways of mounting middleware can be combined.
function mw1(req, res, next) { next(); }
function mw2(req, res, next) { next(); }

var r1 = express.Router();
r1.get('/', function (req, res, next) { next(); });

var r2 = express.Router();
r2.get('/', function (req, res, next) { next(); });

var subApp = express();
subApp.get('/', function (req, res, next) { next(); });

app.use(mw1, [mw2, r1, r2], subApp);

Following are some examples of using the express.static middleware in an Express app.

Serve static content for the apfrom the "public" directory in the application directory.

// GET /style.css etc
app.use(express.static(__dirname + '/public'));

Mount the middleware at "/static" to serve static content only when their request path is prefixed with "/static".

// GET /static/style.css etc.
app.use('/static', express.static(__dirname + '/public'));

Disable logging for static content requests by loading the logger middleware after the static middleware.

app.use(express.static(__dirname + '/public'));
app.use(logger());

Serve static files from multiple directories, but give precedence to "./public" over the others.

app.use(express.static(__dirname + '/public'));
app.use(express.static(__dirname + '/files'));
app.use(express.static(__dirname + '/uploads'));

app.engine(ext, callback)

Register the given template engine callback as ext.

By default, Express will require() the engine based on the file extension. For example if you try to render a "foo.jade" file Express will invoke the following internally, and cache the require() on subsequent calls to increase performance.

app.engine('jade', require('jade').__express);

For engines that do not provide .__express out of the box - or if you wish to "map" a different extension to the template engine you may use this method. For example mapping the EJS template engine to ".html" files:

app.engine('html', require('ejs').renderFile);

In this case EJS provides a .renderFile() method with the same signature that Express expects: (path, options, callback), though note that it aliases this method as ejs.__express internally so if you're using ".ejs" extensions you dont need to do anything.

Some template engines do not follow this convention, the consolidate.js library was created to map all of node's popular template engines to follow this convention, thus allowing them to work seemlessly within Express.

var engines = require('consolidate');
app.engine('haml', engines.haml);
app.engine('html', engines.hogan);

app.param([name], callback)

Map logic to route parameters. For example, when :user is present in a route path, you may map user loading logic to automatically provide req.user to the route, or perform validations on the parameter input.

Note

  • Param callback functions are local to the router on which they are defined. They are not inherited by mounted apps or routers. Hence, param callbacks defined on app will be triggered only by route parameters defined on app routes.
  • A param callback will be called only once in a request-response cycle, even if the parameter is matched in multiple routes.
app.param('id', function (req, res, next, id) {
  console.log('CALLED ONLY ONCE');
  next();
})

app.get('/user/:id', function (req, res, next) {
  console.log('although this matches');
  next();
});

app.get('/user/:id', function (req, res) {
  console.log('and this matches too');
  res.end();
});

The following snippet illustrates how the callback is much like middleware, thus supporting async operations. However, it provides the additional value of the parameter (here named as id), derived from the corresponding parameter in the req.params object. An attempt to load the user is then performed, assigning req.user; otherwise an error is passed to next(err).

app.param('user', function(req, res, next, id){
  User.find(id, function(err, user){
    if (err) {
      next(err);
    } else if (user) {
      req.user = user;
      next();
    } else {
      next(new Error('failed to load user'));
    }
  });
});

Alternatively, you can pass only a callback, in which case you have the opportunity to alter the app.param() API. For example the express-params defines the following callback which allows you to restrict parameters to a given regular expression.

This example is a bit more advanced. It is checking if the second argument is a regular expression, returning the callback, which acts much like the "user" param example.

app.param(function(name, fn){
  if (fn instanceof RegExp) {
    return function(req, res, next, val){
      var captures;
      if (captures = fn.exec(String(val))) {
        req.params[name] = captures;
        next();
      } else {
        next('route');
      }
    }
  }
});

The method could now be used to effectively validate parameters (and optionally parse them to provide capture groups):

app.param('id', /^\d+$/);

app.get('/user/:id', function(req, res){
  res.send('user ' + req.params.id);
});

app.param('range', /^(\w+)\.\.(\w+)?$/);

app.get('/range/:range', function(req, res){
  var range = req.params.range;
  res.send('from ' + range[1] + ' to ' + range[2]);
});

app.METHOD(path, [callback...], callback)

The app.METHOD() methods provide the routing functionality in Express, where METHOD is derived from one of the HTTP or augmented methods, and lowercased. These methods look like app.get(), app.post(), app.patch(), and so on.

The following methods are supported by Express: get, post, put, head, delete, options, trace, copy, lock, mkcol, move, purge, propfind, proppatch, unlock, report, mkactivity, checkout, merge, m-search, notify, subscribe, unsubscribe, patch, search, and connect.

To route methods which translate to invalid JavaScript variable names, use the bracket notation: app['m-search']('/', function () { ... })

Multiple callbacks may be given; all are treated equally, and behave just like middleware. The only exception is 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 if there's no reason to proceed with the current route.

The following snippet illustrates the most simple route definition possible. Express translates the path strings to regular expressions, used internally to match incoming requests. Query strings are not considered when peforming these matches. For example, "GET /" would match the following route, as would "GET /?name=tobi":

app.get('/', function(req, res){
  res.send('hello world');
});

Regular expressions may also be used, and can be useful if you have very specific restraints, for example the following would match "GET /commits/71dbb9c" as well as "GET /commits/71dbb9c..4c084f9".

app.get(/^\/commits\/(\w+)(?:\.\.(\w+))?$/, function(req, res){
  var from = req.params[0];
  var to = req.params[1] || 'HEAD';
  res.send('commit range ' + from + '..' + to);
});

Several callbacks may also be passed, useful for re-using middleware that load resources, perform validations, etc.

app.get('/user/:id', user.load, function(){
  // ... 
})

If you have multiple common middleware for a route, you can use the route API with all.

var middleware = [loadForum, loadThread];

app.route('/forum/:fid/thread/:tid')
.all(loadForum)
.all(loadThread)
.get(function() { //... });
.post(function() { //... });

Both middleware will be run for GET and POST requests.

app.all(path, [callback...], callback)

This method functions just like the app.METHOD() methods, however it matches all HTTP verbs.

This method is extremely useful for mapping "global" logic for specific path prefixes or arbitrary matches. For example if you placed the following route at the top of all other route definitions, it would require that all routes from that point on would require authentication, and automatically load a user. Keep in mind that these callbacks do not have to act as end points, loadUser can perform a task, then next() to continue matching subsequent routes.

app.all('*', requireAuthentication, loadUser);

Or the equivalent:

app.all('*', requireAuthentication)
app.all('*', loadUser);

Another great example of this is white-listed "global" functionality. Here the example is much like before, however only restricting paths prefixed with "/api":

app.all('/api/*', requireAuthentication);

app.route(path)

Returns an instance of a single route, which can then be used to handle HTTP verbs with optional middleware. Using app.route() is a recommended approach for avoiding duplicate route names (and thus typo errors).

var app = express();

app.route('/events')
.all(function(req, res, next) {
  // runs for all HTTP verbs first
  // think of it as route specific middleware!
})
.get(function(req, res, next) {
  res.json(...);
})
.post(function(req, res, next) {
  // maybe add a new event...
})

app.locals

Application local variables are provided to all templates rendered within the application. This is useful for providing helper functions to templates, as well as app-level data.

app.locals.title = 'My App';
app.locals.strftime = require('strftime');
app.locals.email = 'me@myapp.com';

The app.locals object is a JavaScript Object. The properties added to it will be exposed as local variables within the application.

app.locals.title
// => 'My App'

app.locals.email
// => 'me@myapp.com'

By default, Express exposes only a single app-level local variable: settings.

app.set('title', 'My App');
// use settings.title in a view

app.render(view, [options], callback)

Render a view with a callback responding with the rendered string. This is the app-level variant of res.render(), and otherwise behaves the same way.

app.render('email', function(err, html){
  // ...
});

app.render('email', { name: 'Tobi' }, function(err, html){
  // ...
});

app.listen()

Bind and listen for connections on the given host and port. This method is identical to node's http.Server#listen().

var express = require('express');
var app = express();
app.listen(3000);

The app returned by express() is in fact a JavaScript Function, designed to be passed to node's HTTP servers as a callback to handle requests. This allows you to provide both HTTP and HTTPS versions of your app with the same codebase easily, as the app does not inherit from these (it is simply a callback):

var express = require('express');
var https = require('https');
var http = require('http');
var app = express();

http.createServer(app).listen(80);
https.createServer(options, app).listen(443);

The app.listen() method is a convenience method for the following (if you wish to use HTTPS or provide both, use the technique above):

app.listen = function(){
  var server = http.createServer(this);
  return server.listen.apply(server, arguments);
};

app.path()

Returns the canonical path of the app.

var app = express()
  , blog = express()
  , blogAdmin = express();

app.use('/blog', blog);
blog.use('/admin', blogAdmin);

console.log(app.path()); // ''
console.log(blog.path()); // '/blog'
console.log(blogAdmin.path()); // '/blog/admin'

The behavior of this method can become very complicated in complex cases of mounted apps, hence it is recommended to use req.baseUrl to get the canonical path of the app.

app.mountpath

This property refers to the path pattern(s) on which a sub app was mounted.

var admin = express();

admin.get('/', function (req, res) {
  console.log(admin.mountpath); // /admin
  res.send('Admin Homepage');
})

app.use('/admin', admin); // mount the sub app

It is similar to the baseUrl property of the req object, except req.baseUrl returns the matched URL path, instead of the matched pattern(s).

If a sub app is mounted on multiple path patterns, app.mountpath returns the list of patterns it is mounted on, as shown in the following example.

var admin = express();

admin.get('/', function (req, res) {
  console.log(admin.mountpath); // [ '/adm*n', '/manager' ]
  res.send('Admin Homepage');
})

var secret = express();
secret.get('/', function (req, res) {
  console.log(secret.mountpath); // /secr*t
  res.send('Admin Secret');
});

admin.use('/secr*t', secret); // load the 'secret' router on '/secr*t', on the 'admin' sub app
app.use(['/adm*n', '/manager'], admin); // load the 'admin' router on '/adm*n' and '/manager', on the parent app

app.on('mount', callback(parent))

The mount event is fired on a sub app, when it is mounted on a parent app. The parent app is passed to the callback function.

var admin = express();

admin.on('mount', function (parent) {
  console.log('Admin Mounted');
  console.log(parent); // refers to the parent app
});

admin.get('/', function (req, res) {
  res.send('Admin Homepage');
});

app.use('/admin', admin);

Request

req.params

This property is an object containing properties mapped to the named route "parameters". For example, if you have the route /user/:name, then the "name" property is available to you as req.params.name. This object defaults to {}.

// GET /user/tj
req.params.name
// => "tj"

When a regular expression is used for the route definition, capture groups are provided in the array using req.params[N], where N is the nth capture group. This rule is applied to unnamed wild-card matches with string routes such as /file/*:

// GET /file/javascripts/jquery.js
req.params[0]
// => "javascripts/jquery.js"

req.query

This property is an object containing the parsed query-string, defaulting to {}.

// GET /search?q=tobi+ferret
req.query.q
// => "tobi ferret"

// GET /shoes?order=desc&shoe[color]=blue&shoe[type]=converse
req.query.order
// => "desc"

req.query.shoe.color
// => "blue"

req.query.shoe.type
// => "converse"

req.body

Contains the key-value pairs of data submitted in the request body. It is undefined by default, and is populated with the use of a body-parsing middleware such as body-parser and multer.

The example below shows the use of body-parsing middleware to ppopulate req.body.

var app = require('express')();
var bodyParser = require('body-parser');
var multer = require('multer'); 

app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
app.use(multer()); // for parsing multipart/form-data

app.post('/', function (req, res) {

  console.log(req.body);
  res.json(req.body);

})

req.param(name, [defaultValue])

Return the value of param name when present.

// ?name=tobi
req.param('name')
// => "tobi"

// POST name=tobi
req.param('name')
// => "tobi"

// /user/tobi for /user/:name 
req.param('name')
// => "tobi"

Lookup is performed in the following order:

  • req.params
  • req.body
  • req.query

Optionally, you can specify defaultValue to set a default value if the parameter is not found in any of the request objects.

Direct access to req.body, req.params, and req.query should be favoured for clarity - unless you truly accept input from each object. Body-parsing middleware must be loaded for req.param() to work preditably. Refer req.body for details.

req.route

The currently matched Route.

app.get('/user/:id?', function userIdHandler(req, res) {
  console.log(req.route);
  res.send('GET');
})

Example output from the previous snippet:

{ path: '/user/:id?',
  stack:
   [ { handle: [Function: userIdHandler],
       name: 'userIdHandler',
       params: undefined,
       path: undefined,
       keys: [],
       regexp: /^\/?$/i,
       method: 'get' } ],
  methods: { get: true } }

req.cookies

This object requires the cookieParser() middleware for use. It contains cookies sent by the user-agent. If no cookies are sent, it defaults to {}.

// Cookie: name=tj
req.cookies.name
// => "tj"

Please refer to cookie-parser for additional documentation or any issues and concerns.

req.signedCookies

This object requires the cookieParser(secret) middleware for use. It contains signed cookies sent by the user-agent, unsigned and ready for use. Signed cookies reside in a different object to show developer intent; otherwise, a malicious attack could be placed on req.cookie values (which are easy to spoof). Note that signing a cookie does not make it "hidden" or encrypted; this simply prevents tampering (because the secret used to sign is private). If no signed cookies are sent, it defaults to {}.

// Cookie: user=tobi.CP7AWaXDfAKIRfH49dQzKJx7sKzzSoPq7/AcBBRVwlI3
req.signedCookies.user
// => "tobi"

Please refer to cookie-parser for additional documentation or any issues and concerns.

req.get(field)

Get the case-insensitive request header field. The Referrer and Referer fields are interchangeable.

req.get('Content-Type');
// => "text/plain"

req.get('content-type');
// => "text/plain"

req.get('Something');
// => undefined

Aliased as req.header(field).

req.accepts(types)

Check if the given types are acceptable, returning the best match when true, or else undefined (in which case you should respond with 406 "Not Acceptable").

The type value may be a single mime type string (such as "application/json"), the extension name such as "json", a comma-delimited list, or an array. When a list or array is given, the best match (if any) is returned.

// Accept: text/html
req.accepts('html');
// => "html"

// Accept: text/*, application/json
req.accepts('html');
// => "html"
req.accepts('text/html');
// => "text/html"
req.accepts('json, text');
// => "json"
req.accepts('application/json');
// => "application/json"

// Accept: text/*, application/json
req.accepts('image/png');
req.accepts('png');
// => undefined

// Accept: text/*;q=.5, application/json
req.accepts(['html', 'json']);
req.accepts('html, json');
// => "json"

Please refer to accepts for additional documentation or any issues and concerns.

req.acceptsCharsets(charset, ...)

Check if the given charset are acceptable.

Please refer to accepts for additional documentation or any issues and concerns.

req.acceptsLanguages(lang, ...)

Check if the given lang are acceptable.

Please refer to accepts for additional documentation or any issues and concerns.

req.acceptsEncodings(encoding, ...)

Check if the given encoding are acceptable.

Please refer to accepts for additional documentation or any issues and concerns.

req.is(type)

Check if the incoming request contains the "Content-Type" header field, and if it matches the give mime type.

// With Content-Type: text/html; charset=utf-8
req.is('html');
req.is('text/html');
req.is('text/*');
// => true

// When Content-Type is application/json
req.is('json');
req.is('application/json');
req.is('application/*');
// => true

req.is('html');
// => false

Please refer to type-is for additional documentation or any issues and concerns.

req.ip

Return the remote address (or, if "trust proxy" is enabled, the upstream address).

req.ip
// => "127.0.0.1"

req.ips

When "trust proxy" is true, parse the "X-Forwarded-For" ip address list and return an array. Otherwise, an empty array is returned.

For example, if the value were "client, proxy1, proxy2", you would receive the array ["client", "proxy1", "proxy2"], where "proxy2" is the furthest down-stream.

req.path

Returns the request URL pathname.

// example.com/users?sort=desc
req.path
// => "/users"

req.hostname

Returns the hostname from the "Host" header field.

// Host: "example.com:3000"
req.hostname
// => "example.com"

req.fresh

Check if the request is "fresh" (i.e. whether the Last-Modified and/or the ETag still match).

req.fresh
// => true

Please refer to fresh for additional documentation or any issues and concerns.

req.stale

Check if the request is "stale" (i.e. the Last-Modified and/or ETag headers do not match).

req.stale
// => true

req.xhr

Check if the request was issued with the "X-Requested-With" header field set to "XMLHttpRequest" (jQuery etc).

req.xhr
// => true

req.protocol

Return the protocol string "http" or "https" when requested with TLS. If the "trust proxy" setting is enabled, the "X-Forwarded-Proto" header field will be trusted. If you're running behind a reverse proxy that supplies https for you, this may be enabled.

req.protocol
// => "http"

req.secure

Check if a TLS connection is established. This is a short-hand for:

'https' == req.protocol;

req.subdomains

Return subdomains as an array.

// Host: "tobi.ferrets.example.com"
req.subdomains
// => ["ferrets", "tobi"]

req.originalUrl

This property is much like req.url; however, it retains the original request url, allowing you to rewrite req.url freely for internal routing purposes. For example, the "mounting" feature of app.use() will rewrite req.url to strip the mount point.

// GET /search?q=something
req.originalUrl
// => "/search?q=something"

req.baseUrl

This property refers to the URL path, on which a router instance was mounted.

var greet = express.Router();

greet.get('/jp', function (req, res) {
  console.log(req.baseUrl); // /greet
  res.send('Konichiwa!');
});

app.use('/greet', greet); // load the router on '/greet'

Even if a path pattern or a set of path patterns were used to load the router, the matched string is returned as the baseUrl, instead of the pattern(s). In the following example, the greet router is loaded on two path patterns.

app.use(['/gre+t', '/hel{2}o'], greet); // load the router on '/gre+t' and '/hel{2}o'

When the request is made to /greet/jp, req.baseUrl will be equal to "/greet"; and when the request is made to /hello/jp, it will be equal to "/hello".

req.baseUrl is similar to the mountpath property of the app object, except app.mountpath returns the matched path pattern(s).

Response

res.status(code)

Chainable alias of node's res.statusCode. Use this method to set the HTTP status for the response.

res.status(403).end();
res.status(400).send('Bad Request');
res.status(404).sendFile('/absolute/path/to/404.png');

res.set(field, [value])

Set header field to value, or pass an object to set multiple fields at once.

res.set('Content-Type', 'text/plain');

res.set({
  'Content-Type': 'text/plain',
  'Content-Length': '123',
  'ETag': '12345'
})

Aliased as res.header(field, [value]).

res.get(field)

Get the case-insensitive response header field.

res.get('Content-Type');
// => "text/plain"

res.cookie(name, value, [options])

Set cookie name to value, which may be a string or object converted to JSON. The path option defaults to "/".

res.cookie('name', 'tobi', { domain: '.example.com', path: '/admin', secure: true });
res.cookie('rememberme', '1', { expires: new Date(Date.now() + 900000), httpOnly: true });

The maxAge option is a convenience option for setting "expires" relative to the current time in milliseconds. The following is equivalent to the previous example.

res.cookie('rememberme', '1', { maxAge: 900000, httpOnly: true })

An object may be passed which is then serialized as JSON, which is automatically parsed by the bodyParser() middleware.

res.cookie('cart', { items: [1,2,3] });
res.cookie('cart', { items: [1,2,3] }, { maxAge: 900000 });

Signed cookies are also supported through this method. Simply pass the signed option. When given res.cookie() will use the secret passed to cookieParser(secret) to sign the value.

res.cookie('name', 'tobi', { signed: true });

Later you may access this value through the req.signedCookie object.

res.clearCookie(name, [options])

Clear cookie name. The path option defaults to "/".

res.cookie('name', 'tobi', { path: '/admin' });
res.clearCookie('name', { path: '/admin' });

res.redirect([status], url)

Express passes the specified URL string as-is to the browser in the Location header, without any validation or manipulation, except in case of back.

Browsers take the responsibility of deriving the intended URL from the current URL or the referring URL, and the URL specified in the Location header; and redirect the user accordingly.

Redirect to the given url with optional status code defaulting to 302 "Found".

res.redirect('/foo/bar');
res.redirect('http://example.com');
res.redirect(301, 'http://example.com');
res.redirect('../login');

Redirects can be a fully qualified URI for redirecting to a different site:

res.redirect('http://google.com');

Redirects can be relative to the root of the host name. For example, if you were on http://example.com/admin/post/new, the following redirect to /admin would land you at http://example.com/admin:

res.redirect('/admin');

Redirects can be relative to the current URL. A redirection of post/new, from http://example.com/blog/admin/ (notice the trailing slash), would give you http://example.com/blog/admin/post/new.

res.redirect('post/new');

Redirecting to post/new from http://example.com/blog/admin (no trailing slash), will take you to http://example.com/blog/post/new.

If you found the above behavior confusing, think of path segments as directories (have trailing slashes) and files, it will start to make sense.

Pathname relative redirects are also possible. If you were on http://example.com/admin/post/new, the following redirect would land you at http//example.com/admin/post:

res.redirect('..');

A back redirection will redirect the request back to the Referer (or Referrer), defaulting to / when missing.

res.redirect('back');

res.location

Set the location header.

res.location('/foo/bar');
res.location('foo/bar');
res.location('http://example.com');
res.location('../login');
res.location('back');

You can use the same kind of urls as in res.redirect().

For example, if your application is mounted at /blog, the following would set the location header to /blog/admin:

res.location('admin')

res.send([body])

Send a response.

res.send(new Buffer('whoop'));
res.send({ some: 'json' });
res.send('<p>some html</p>');
res.status(404).send('Sorry, we cannot find that!');
res.status(500).send({ error: 'something blew up' });

This method performs a myriad of useful tasks for simple non-streaming responses such as automatically assigning the Content-Length unless previously defined and providing automatic HEAD and HTTP cache freshness support.

When a Buffer is given the Content-Type is set to "application/octet-stream" unless previously defined as shown below:

res.set('Content-Type', 'text/html');
res.send(new Buffer('<p>some html</p>'));

When a String is given the Content-Type is set defaulted to "text/html":

res.send('<p>some html</p>');

When an Array or Object is given Express will respond with the JSON representation:

res.send({ user: 'tobi' });
res.send([1,2,3]);

res.json([body])

Send a JSON response. This method is identical to res.send() when an object or array is passed. However, it may be used for explicit JSON conversion of non-objects, such as null, undefined, etc. (although these are technically not valid JSON).

res.json(null)
res.json({ user: 'tobi' })
res.status(500).json({ error: 'message' })

res.jsonp([body])

Send a JSON response with JSONP support. This method is identical to res.json(), except that it opts-in to JSONP callback support.

res.jsonp(null)
// => null

res.jsonp({ user: 'tobi' })
// => { "user": "tobi" }

res.status(500).jsonp({ error: 'message' })
// => { "error": "message" }

By default, the JSONP callback name is simply callback. However, you may alter this with the jsonp callback name setting. The following are some examples of JSONP responses using the same code:

// ?callback=foo
res.jsonp({ user: 'tobi' })
// => foo({ "user": "tobi" })

app.set('jsonp callback name', 'cb');

// ?cb=foo
res.status(500).jsonp({ error: 'message' })
// => foo({ "error": "message" })

res.type(type)

Sets the Content-Type to the mime lookup of type, or when "/" is present the Content-Type is simply set to this literal value.

res.type('.html');
res.type('html');
res.type('json');
res.type('application/json');
res.type('png');

res.format(object)

Performs content-negotiation on the Accept HTTP header on the request object, when present. It uses req.accepts() to select a handler for the request, based on the acceptable types ordered by their quality values. If the header is not specified, the first callback is invoked. When no match is found, the server responds with 406 "Not Acceptable", or invokes the default callback.

The Content-Type response header is set for you when a callback is selected. However, you may alter this within the callback using res.set() or res.type() etcetera.

The following example would respond with { "message": "hey" } when the Accept header field is set to "application/json" or "*/json" (however if "*/*" is given, then "hey" will be the response).

res.format({
  'text/plain': function(){
    res.send('hey');
  },

  'text/html': function(){
    res.send('<p>hey</p>');
  },

  'application/json': function(){
    res.send({ message: 'hey' });
  },

  'default': function() {
    // log the request and respond with 406
    res.status(406).send('Not Acceptable');
  }
});

In addition to canonicalized MIME types, you may also use extension names mapped to these types for a slightly less verbose implementation:

res.format({
  text: function(){
    res.send('hey');
  },

  html: function(){
    res.send('<p>hey</p>');
  },

  json: function(){
    res.send({ message: 'hey' });
  }
});

res.attachment([filename])

Sets the Content-Disposition header field to "attachment". If a filename is given, then the Content-Type will be automatically set based on the extname via res.type(), and the Content-Disposition's "filename=" parameter will be set.

res.attachment();
// Content-Disposition: attachment

res.attachment('path/to/logo.png');
// Content-Disposition: attachment; filename="logo.png"
// Content-Type: image/png

res.sendFile(path, [options], [fn])

Note: res.sendFile requires Express version to be at least 4.8.0

Transfer the file at the given path. The Content-Type response header field is automatically set based on the filename's extension.

Unless the root option is set in the options object, path must be an absolute path of the file.

Options:

  • maxAge sets the max-age property of the Cache-Control header in milliseconds or a string in ms format, defaults to 0.
  • root root directory for relative filenames.
  • lastModified enabled by default, sets the Last-Modified header to the last modified date of the file on the OS. Set false to disable it.
  • headers object of HTTP headers to serve with the file.
  • dotfiles option for serving dotfiles. Possible values are "allow", "deny", "ignore"; defaults to "ignore".

The callback fn(err) is invoked when the transfer is complete or when an error occurs. If the callback function is specified and an error occurs, the response process must be handled explicitly within the callback function by either ending the request response cycle, or passing the control to the next route.

Here is an example of using res.sendFile with all its arguments.

app.get('/file/:name', function (req, res, next) {

  var options = {
    root: __dirname + '/public/',
    dotfiles: 'deny',
    headers: {
        'x-timestamp': Date.now(),
        'x-sent': true
    }
  };

  var fileName = req.params.name;
  res.sendFile(fileName, options, function (err) {
    if (err) {
      console.log(err);
      res.status(err.status).end();
    }
    else {
      console.log('Sent:', fileName);
    }
  });

})

res.sendFile provides fine-grained support for file serving as illustrated in the following example:

app.get('/user/:uid/photos/:file', function(req, res){
  var uid = req.params.uid
    , file = req.params.file;

  req.user.mayViewFilesFrom(uid, function(yes){
    if (yes) {
      res.sendFile('/uploads/' + uid + '/' + file);
    } else {
      res.status(403).send('Sorry! you cant see that.');
    }
  });
});

Please refer to send for additional documentation or any issues and concerns.

res.sendStatus(statusCode)

Set the response HTTP status code to statusCode and send its string representation as the response body.

res.sendStatus(200); // equivalent to res.status(200).send('OK')
res.sendStatus(403); // equivalent to res.status(403).send('Forbidden')
res.sendStatus(404); // equivalent to res.status(404).send('Not Found')
res.sendStatus(500); // equivalent to res.status(500).send('Internal Server Error')

If an unspported status code is specified, the HTTP status is still set to statusCode and the string version of the code is sent as the response body.

res.sendStatus(2000); // equivalent to res.status(2000).send('2000')

More about HTTP Status Codes

res.download(path, [filename], [fn])

Transfer the file at path as an "attachment". Typically, browsers will prompt the user for download. The Content-Disposition "filename=" parameter (i.e. the one that will appear in the brower dialog) is set to path by default. However, you may provide an override filename.

When an error has ocurred or transfer is complete the optional callback fn is invoked. This method uses res.sendFile() to transfer the file.

res.download('/report-12345.pdf');

res.download('/report-12345.pdf', 'report.pdf');

res.download('/report-12345.pdf', 'report.pdf', function(err){
  if (err) {
    // handle error, keep in mind the response may be partially-sent
    // so check res.headersSent
  } else {
    // decrement a download credit etc
  }
});

Join the given links to populate the "Link" response header field.

res.links({
  next: 'http://api.example.com/users?page=2',
  last: 'http://api.example.com/users?page=5'
});

yields:

Link: &lt;http://api.example.com/users?page=2&gt;; rel="next", 
      &lt;http://api.example.com/users?page=5&gt;; rel="last"

res.locals

Response local variables are scoped to the request, and therefore only available to the view(s) rendered during that request / response cycle (if any). Otherwise, this API is identical to app.locals.

This object is useful for exposing request-level information such as the request pathname, authenticated user, user settings etc.

app.use(function(req, res, next){
  res.locals.user = req.user;
  res.locals.authenticated = ! req.user.anonymous;
  next();
});

res.render(view, [locals], callback)

Render a view with a callback responding with the rendered string. When an error occurs next(err) is invoked internally. When a callback is provided both the possible error and rendered string are passed, and no automated response is performed.

res.render('index', function(err, html){
  // ...
});

res.render('user', { name: 'Tobi' }, function(err, html){
  // ...
});

res.vary(field)

Adds the field to the Vary response header, if it is not there already.

res.vary('User-Agent').render('docs');

res.end([data], [encoding])

Inherited from node's http.ServerResponse, ends the response process. The only recommended use is for quickly ending the response without any data. If you need to respond with data, use Express' response methods such as res.send(), res.json() etc.

res.end();
res.status(404).end();

res.headersSent

Property indicating if HTTP headers has been sent for the response.

app.get('/', function (req, res) {
  console.log(res.headersSent); // false
  res.send('OK');
  console.log(res.headersSent); // true
})

Router

Router()

A router is an isolated instance of middleware and routes. Routers can be thought of as "mini" applications, capable only of performing middleware and routing functions. Every express application has a built-in app router.

Routers behave like middleware themselves and can be ".use()'d" by the app or in other routers.

Create a new router with express.Router():

var router = express.Router([options]);

Options is an optional object to alter the behavior of the router.

  • caseSensitive Enable case sensitivity, disabled by default, treating "/Foo" and "/foo" as the same
  • strict Enable strict routing, by default "/foo" and "/foo/" are treated the same by the router
  • mergeParams Ensure the req.params values from the parent router are preserved. If the parent and the child have conflicting param names, the child's value take precedence. Defaults to false.

The router can have middleware and http VERB routes added just like an application.

// invoked for any requests passed to this router
router.use(function(req, res, next) {
  // .. some logic here .. like any other middleware
  next();
});

// will handle any request that ends in /events
// depends on where the router is "use()'d"
router.get('/events', function(req, res, next) {
  // ..
});

You can then use a router for a particular root url in this way separating your routes into files or even mini apps.

// only requests to /calendar/* will be sent to our "router"
app.use('/calendar', router);

router.use([path], [function...], function)

The interface is similar to app.use(). A simple example and usecase is described below, read the app.use() documentation for the details.

Use the given middleware function, with optional mount path, defaulting to "/".

Middleware is like a plumbing pipe, requests start at the first middleware you define and work their way "down" the middleware stack processing for each path they match.

var express = require('express');
var app = express();
var router = express.Router();

// simple logger for this router's requests
// all requests to this router will first hit this middleware
router.use(function(req, res, next) {
  console.log('%s %s %s', req.method, req.url, req.path);
  next();
});

// this will only be invoked if the path starts with /bar from the mount point
router.use('/bar', function(req, res, next) {
  // ... maybe some additional /bar logging ...
  next();
});

// always invoked
router.use(function(req, res, next) {
  res.send('Hello World');
});

app.use('/foo', router);

app.listen(3000);

The "mount" path is stripped and is not visible to the middleware function. The main effect of this feature is that mounted middleware may operate without code changes regardless of its "prefix" pathname.

The order of which middleware are "defined" using router.use() is very important, they are invoked sequentially, thus this defines middleware precedence. For example usually a logger is the very first middleware you would use, logging every request:

var logger = require('morgan');

router.use(logger());
router.use(express.static(__dirname + '/public'));
router.use(function(req, res){
  res.send('Hello');
});

Now suppose you wanted to ignore logging requests for static files, but to continue logging routes and middleware defined after logger(), you would simply move static() above:

router.use(express.static(__dirname + '/public'));
router.use(logger());
router.use(function(req, res){
  res.send('Hello');
});

Another concrete example would be serving files from multiple directories, giving precedence to "./public" over the others:

app.use(express.static(__dirname + '/public'));
app.use(express.static(__dirname + '/files'));
app.use(express.static(__dirname + '/uploads'));

router.param([name], callback)

Map logic to route parameters. For example, when :user is present in a route path you may map user loading logic to automatically provide req.user to the route, or perform validations on the parameter input.

Note

  • Param callback functions are local to the router on which they are defined. They are not inherited by mounted apps or routers. Hence, param callbacks defined on router will be trigerred only by route parameters defined on router routes.

  • A param callback will be called only once in a request-response cycle, even if the parameter is matched in multiple routes.

    app.param('id', function (req, res, next, id) {
      console.log('CALLED ONLY ONCE');
      next();
    })
    
    app.get('/user/:id', function (req, res, next) {
      console.log('although this matches');
      next();
    });
    
    app.get('/user/:id', function (req, res) {
      console.log('and this matches too');
      res.end();
    });
    

    The following snippet illustrates how the callback is much like middleware, thus supporting async operations. However, it provides the additional value of the parameter (here named as id), derived from the corresponding parameter in the req.params object. An attempt to load the user is then performed, assigning req.user, otherwise passing an error to next(err).

It is important to realize that any route that triggered a named parameter function to run will only be run if next was not called with an error in the named parameter handler.

router.param('user', function(req, res, next, id){
  User.find(id, function(err, user){
    if (err) {
      return next(err);
    }
    else if (!user) {
      return next(new Error('failed to load user'));
    }

    req.user = user;
    next();
  });
});

// this route uses the ":user" named parameter
// which will cause the 'user' param callback to be triggered
router.get('/users/:user', function(req, res, next) {
  // req.user WILL be defined here
  // if there was an error, normal error handling will be triggered
  // and this function will NOT execute
});

Alternatively you may pass only a callback, in which case you have the opportunity to alter the router.param() API. For example the express-params defines the following callback which allows you to restrict parameters to a given regular expression.

This example is a bit more advanced. It checks whether the second argument is a regular expression, returning the callback (which acts much like the "user" param example).

router.param(function(name, fn){
  if (fn instanceof RegExp) {
    return function(req, res, next, val){
      var captures;
      if (captures = fn.exec(String(val))) {
        req.params[name] = captures;
        next();
      } else {
        next('route');
      }
    }
  }
});

The method could now be used to effectively validate parameters (and optionally parse them to provide capture groups):

router.param('id', /^\d+$/);

router.get('/user/:id', function(req, res){
  res.send('user ' + req.params.id);
});

router.param('range', /^(\w+)\.\.(\w+)?$/);

router.get('/range/:range', function(req, res){
  var range = req.params.range;
  res.send('from ' + range[1] + ' to ' + range[2]);
});

The router.use() method also supports named parameters so that your mount points for other routers can benefit from preloading using named parameters.

router.route(path)

Returns an instance of a single route which can then be used to handle HTTP verbs with optional middleware. Using router.route() is a recommended approach to avoiding duplicate route naming and thus typo errors.

Building on the router.param() example from before, we see how router.route() allows us to easily specify the various HTTP verb handlers.

var router = express.Router();

router.param('user_id', function(req, res, next, id) {
  // sample user, would actually fetch from DB, etc...
  req.user = {
    id: id,
    name: 'TJ'
  };
  next();
});

router.route('/users/:user_id')
.all(function(req, res, next) {
  // runs for all HTTP verbs first
  // think of it as route specific middleware!
})
.get(function(req, res, next) {
  res.json(req.user);
})
.put(function(req, res, next) {
  // just an example of maybe updating the user
  req.user.name = req.params.name;
  // save user ... etc
  res.json(req.user);
})
.post(function(req, res, next) {
  next(new Error('not implemented'));
})
.delete(function(req, res, next) {
  next(new Error('not implemented'));
})

This apporach re-uses the single '/users/:user_id' path and add handlers for the various HTTP verbs.

router.METHOD(path, [callback...], callback)

The router.METHOD() methods provide the routing functionality in Express, where METHOD is one of the HTTP verbs, such as router.post(). Multiple callbacks may be given, all are treated equally, and 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.

The following snippet illustrates the most simple route definition possible. Express translates the path strings to regular expressions, used internally to match incoming requests. Query strings are not considered when peforming these matches, for example "GET /" would match the following route, as would "GET /?name=tobi".

router.get('/', function(req, res){
  res.send('hello world');
});

Regular expressions may also be used, and can be useful if you have very specific restraints, for example the following would match "GET /commits/71dbb9c" as well as "GET /commits/71dbb9c..4c084f9".

router.get(/^\/commits\/(\w+)(?:\.\.(\w+))?$/, function(req, res){
  var from = req.params[0];
  var to = req.params[1] || 'HEAD';
  res.send('commit range ' + from + '..' + to);
});

router.all(path, [callback...], callback)

This method functions just like the router.METHOD() methods, except that it matches all HTTP verbs.

This method is extremely useful for mapping "global" logic for specific path prefixes or arbitrary matches. For example, if you placed the following route at the top of all other route definitions, it would require that all routes from that point on would require authentication, and automatically load a user. Keep in mind that these callbacks do not have to act as end points; loadUser can perform a task, then next() to continue matching subsequent routes.

router.all('*', requireAuthentication, loadUser);

Or the equivalent:

router.all('*', requireAuthentication)
router.all('*', loadUser);

Another great example of this is white-listed "global" functionality. Here the example is much like before, but it only restricts paths prefixed with "/api":

router.all('/api/*', requireAuthentication);

Middleware

Please refer the Using middleware guide .