Editar en GitHub

Objeto Application

El objeto app denota convencionalmente la aplicación Express. Créalo llamando a la función express() de nivel superior exportada por el módulo Express:

var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send('hello world');
});
app.listen(3000);

Propiedades

app.locals

Las variables locales de la aplicación se proporcionan a todas las plantillas renderizadas dentro de la aplicación. Esto es útil para proporcionar funciones de ayuda a las plantillas, así como datos a nivel de aplicación.

app.locals.title = 'My App';
app.locals.strftime = require('strftime');

El objeto app.locals es una Function de JavaScript, que cuando se invoca con un objeto fusiona las propiedades en sí mismo, proporcionando una forma sencilla de exponer objetos existentes como variables locales.

app.locals({
title: 'My App',
phone: '1-250-858-9990',
email: 'me@myapp.com',
});
console.log(app.locals.title);
// => 'My App'
console.log(app.locals.email);
// => 'me@myapp.com'

Una consecuencia de que el objeto app.locals sea en última instancia un objeto Function de JavaScript es que no debes reutilizar propiedades nombradas existentes (nativas) para tus propios nombres de variables, como name, apply, bind, call, arguments, length, constructor.

app.locals({ name: 'My App' });
console.log(app.locals.name);
// => return 'app.locals' in place of 'My App' (app.locals is a Function !)
// => if name's variable is used in a template, a ReferenceError will be returned.

La lista completa de propiedades nombradas nativas se puede encontrar en muchas especificaciones. La especificación de JavaScript introdujo propiedades originales, algunas de las cuales todavía son reconocidas por los motores modernos, y la especificación de EcmaScript luego construyó sobre ella y normalizó el conjunto de propiedades, agregando nuevas y eliminando las obsoletas. Revisa las propiedades de Functions y Objects si te interesa.

Por defecto Express expone solo una variable local a nivel de aplicación, settings.

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

app.routes

El objeto app.routes alberga todas las rutas definidas mapeadas por el verbo HTTP asociado. Este objeto puede usarse para capacidades de introspección, por ejemplo Express lo usa internamente no solo para enrutamiento sino para proporcionar valores por defecto

OPTIONS behavior unless app.options() is used. Your application or framework may also remove routes by simply by removing them from this object.

La salida de console.log(app.routes):

{ get:
[ { path: '/',
method: 'get',
callbacks: [Object],
keys: [],
regexp: /^\/\/?$/i },
{ path: '/user/:id',
method: 'get',
callbacks: [Object],
keys: [{ name: 'id', optional: false }],
regexp: /^\/user\/(?:([^\/]+?))\/?$/i } ],
delete:
[ { path: '/user/:id',
method: 'delete',
callbacks: [Object],
keys: [Object],
regexp: /^\/user\/(?:([^\/]+?))\/?$/i } ] }

settings

Las siguientes configuraciones se proporcionan para alterar el comportamiento de Express:

  • env Modo de entorno, por defecto process.env.NODE_ENV o "development"
  • trust proxy Habilita el soporte de proxy inverso, deshabilitado por defecto
  • jsonp callback name Cambia el nombre predeterminado del callback de ?callback=
  • json replacer Callback reemplazador de JSON, null por defecto
  • json spaces Espacios de respuesta JSON para formato, por defecto 2 en desarrollo, 0 en producción
  • case sensitive routing Habilita la sensibilidad a mayúsculas y minúsculas, deshabilitado por defecto, tratando "/Foo" y "/foo" como iguales
  • strict routing Habilita el enrutamiento estricto, por defecto "/foo" y "/foo/" son tratados igual por el router
  • view cache Habilita el caché de compilación de plantillas de vista, habilitado en producción por defecto
  • view engine La extensión de motor predeterminada a usar cuando se omite
  • views La ruta del directorio de vistas, por defecto "process.cwd() + '/views'"

Métodos

app.set(name, value)

Asigna la configuración name al valor value.

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

app.get(name)

Obtiene el valor de la configuración name.

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

app.enable(name)

Establece la configuración name en true.

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

app.disable(name)

Establece la configuración name en false.

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

app.enabled(name)

Verifica si la configuración name está habilitada.

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

app.disabled(name)

Verifica si la configuración name está deshabilitada.

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

app.configure([env], callback)

Invoca condicionalmente callback cuando env coincide con app.get('env'), es decir, process.env.NODE_ENV. Este método se mantiene por razones de compatibilidad, y es efectivamente una sentencia if como se ilustra en los siguientes fragmentos. Estas funciones no son necesarias para usar app.set() y otros métodos de configuración.

// all environments
app.configure(function () {
app.set('title', 'My Application');
});
// development only
app.configure('development', function () {
app.set('db uri', 'localhost/dev');
});
// production only
app.configure('production', function () {
app.set('db uri', 'n.n.n.n/prod');
});

Es efectivamente azúcar sintáctica para:

// all environments
app.set('title', 'My Application');
// development only
if (app.get('env') === 'development') {
app.set('db uri', 'localhost/dev');
}
// production only
if (app.get('env') === 'production') {
app.set('db uri', 'n.n.n.n/prod');
}

app.use([path], function)

Usa la function de middleware dada, con una path de montaje opcional, por defecto "/".

var express = require('express');
var app = express();
// simple logger
app.use(function (req, res, next) {
console.log('%s %s', req.method, req.url);
next();
});
// respond
app.use(function (req, res, next) {
res.send('Hello World');
});
app.listen(3000);

La ruta de "montaje" se elimina y no es visible para la function de middleware. El efecto principal de esta característica es que el middleware montado puede operar sin cambios en el código independientemente de su ruta de "prefijo".

Precaución

Una ruta coincidirá con cualquier ruta que siga a su ruta inmediatamente con un "/" o un ".". Por ejemplo: app.use('/apple', ...) coincidirá con /apple, /apple/images, /apple/images/news, /apple.html, /apple.html.txt, y así sucesivamente.

Aquí hay un ejemplo concreto, toma el caso de uso típico de servir archivos en ./public usando el middleware express.static():

// GET /javascripts/jquery.js
// GET /style.css
// GET /favicon.ico
app.use(express.static(path.join(__dirname, 'public')));

Digamos por ejemplo que quieres prefijar todos los archivos estáticos con "/static", podrías usar la característica de "montaje" para soportar esto. Las funciones de middleware montadas no se invocan a menos que req.url contenga este prefijo, momento en el que se elimina cuando se invoca la función. Esto afecta solo a esta función, el middleware subsiguiente verá req.url con "/static" incluido a menos que también estén montadas.

// GET /static/javascripts/jquery.js
// GET /static/style.css
// GET /static/favicon.ico
app.use('/static', express.static(path.join(__dirname, 'public')));

El orden en que el middleware se "define" usando app.use() es muy importante, se invocan secuencialmente, por lo tanto esto define la precedencia del middleware. Por ejemplo usualmente express.logger() es el primer middleware que usarías, registrando cada solicitud:

app.use(express.logger());
app.use(express.static(path.join(__dirname, 'public')));
app.use(function (req, res) {
res.send('Hello');
});

Ahora supón que quieres ignorar el registro de solicitudes para archivos estáticos, pero continuar registrando rutas y middleware definidos después de logger(), simplemente mueve static() arriba:

app.use(express.static(path.join(__dirname, 'public')));
app.use(express.logger());
app.use(function (req, res) {
res.send('Hello');
});

Otro ejemplo concreto sería servir archivos desde múltiples directorios, dando precedencia a "./public" sobre los demás:

app.use(express.static(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'files')));
app.use(express.static(path.join(__dirname, 'uploads')));

app.engine(ext, callback)

Registra el callback del motor de plantillas dado como ext

Por defecto hará require() del motor basándose en la extensión del archivo. Por ejemplo si intentas renderizar un archivo "foo.jade" Express invocará lo siguiente internamente, y almacenará en caché el require() en llamadas subsiguientes para aumentar el rendimiento.

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

Para motores que no proporcionan .__express listo para usar - o si deseas "mapear" una extensión diferente al motor de plantillas puedes usar este método. Por ejemplo mapear el motor de plantillas EJS a archivos ".html":

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

En este caso EJS proporciona un método .renderFile() con la misma firma que Express espera: (path, options, callback), aunque ten en cuenta que aliasa este método como ejs.__express internamente por lo que si usas extensiones ".ejs" no necesitas hacer nada.

Algunos motores de plantillas no siguen esta convención, la

La librería consolidate.js fue creada para mapear todos los motores de plantillas populares de node para seguir esta convención, permitiendo así que funcionen sin problemas dentro de Express.

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

app.param([name], callback)

Mapea lógica a los parámetros de ruta. Por ejemplo cuando :user está presente en una ruta puedes mapear la lógica de carga de usuario para proporcionar automáticamente req.user a la ruta, o realizar validaciones sobre la entrada del parámetro.

El siguiente fragmento ilustra cómo el callback es muy parecido a middleware, soportando operaciones asíncronas, sin embargo proporciona el valor adicional del parámetro, aquí llamado id. Luego se realiza un intento de cargar el usuario, asignando req.user, de lo contrario pasando un error a 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'));
}
});
});

Alternativamente puedes pasar solo un callback, en cuyo caso tienes la oportunidad de alterar la API de app.param(). Por ejemplo express-params define el siguiente callback que te permite restringir parámetros a una expresión regular dada.

Este ejemplo es un poco más avanzado, verificando si el segundo argumento es una expresión regular, devolviendo el callback que actúa muy parecido al ejemplo del parámetro "user".

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');
}
};
}
});

El método ahora podría usarse para validar efectivamente parámetros, o también analizarlos para proporcionar grupos de captura:

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.VERB(path, [callback…], callback)

Los métodos app.VERB() proporcionan la funcionalidad de enrutamiento en Express, donde VERB es uno de los verbos HTTP, como por ejemplo app.post(). Se pueden proporcionar múltiples callbacks, todos son tratados equitativamente, y se comportan como middleware, con la única excepción de que estos callbacks pueden invocar next('route') para omitir los callback(s) de ruta restantes. Este mecanismo puede usarse para realizar pre-condiciones en una ruta y luego pasar el control a las rutas subsiguientes cuando no hay razón para proceder con la ruta coincidente.

El siguiente fragmento ilustra la definición de ruta más simple posible. Express traduce las cadenas de ruta a expresiones regulares, usadas internamente para coincidir con las solicitudes entrantes. Las cadenas de consulta no se consideran al realizar estas coincidencias, por ejemplo "GET /" coincidiría con la siguiente ruta, al igual que "GET /?name=tobi".

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

También se pueden usar expresiones regulares, y pueden ser útiles si tienes restricciones muy específicas, por ejemplo lo siguiente coincidiría con "GET /commits/71dbb9c" así como con "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);
});

También se pueden pasar varios callbacks, útil para reutilizar middleware que carga recursos, realiza validaciones, etc.

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

Estos callbacks también pueden pasarse dentro de arrays, estos arrays se aplanan simplemente al pasarse:

var middleware = [loadForum, loadThread];
app.get('/forum/:fid/thread/:tid', middleware, function () {
// ...
});
app.post('/forum/:fid/thread/:tid', middleware, function () {
// ...
});

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

Este método funciona igual que los métodos app.VERB(), sin embargo coincide con todos los verbos HTTP.

Este método es extremadamente útil para mapear lógica "global" para prefijos de ruta específicos o coincidencias arbitrarias. Por ejemplo si colocas la siguiente ruta al principio de todas las demás definiciones de rutas, requeriría que todas las rutas a partir de ese punto requerirían autenticación, y cargarían automáticamente un usuario. Ten en mente que estos callbacks no tienen que actuar como puntos finales, loadUser puede realizar una tarea, luego next() para continuar coincidiendo con rutas subsiguientes.

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

O el equivalente:

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

Otro gran ejemplo de esto es la funcionalidad "global" con lista blanca. Aquí el ejemplo es muy parecido al anterior, sin embargo solo restringiendo rutas prefijadas con "/api":

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

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

Renderiza una view con un callback que responde con la cadena renderizada. Esta es la variante a nivel de aplicación de res.render(), y por lo demás se comporta de la misma manera.

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

app.listen()

Vincula y escucha conexiones en el host y puerto dados, este método es idéntico a http.Server#listen() de node.

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

El app devuelto por express() es de hecho una Function de JavaScript, diseñada para pasarse a los servidores http de node como callback para manejar solicitudes. Esto te permite proporcionar tanto versiones HTTP como HTTPS de tu app con la misma base de código fácilmente, ya que la app no hereda de estos, es simplemente un 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);

El método app.listen() es simplemente un método de conveniencia definido como, si deseas usar HTTPS o proporcionar ambos, usa la técnica anterior.

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