Router

Un objeto router es una instancia de middleware y rutas. Puedes pensar en él como una “mini-aplicación,” capaz solo de realizar funciones de middleware y enrutamiento. Cada aplicación Express tiene un router de aplicación integrado.

Un router se comporta como middleware en sí mismo, así que puedes usarlo como argumento de app.use() o como argumento del método use() de otro router.

El objeto express de nivel superior tiene un método Router() que crea un nuevo objeto router.

Una vez que has creado un objeto router, puedes añadir middleware y rutas de métodos HTTP (como get, put, post, etc.) a él igual que en una aplicación. Por ejemplo:

// 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) {
// ..
});

Puedes entonces usar un router para una URL raíz particular de esta forma, separando tus rutas en archivos o incluso mini-aplicaciones.

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

Métodos

Router()

Argumentos

options
Tipo: Object | undefined

Opciones que configuran el comportamiento del router.

caseSensitive
Tipo: Boolean Por defecto: false

Activa la sensibilidad a mayúsculas/minúsculas. Desactivado por defecto, tratando /Foo y /foo como iguales.

mergeParams
Tipo: Boolean Por defecto: false

Preserva los valores de req.params del router padre. Si el padre y el hijo tienen nombres de parámetros en conflicto, el valor del hijo tiene prioridad.

strict
Tipo: Boolean Por defecto: false

Habilita el enrutamiento estricto. Deshabilitado por defecto, /foo y /foo/ son tratados de la misma manera por el router.

Crea un nuevo objeto router.

index.cjs
var express = require('express');
var router = express.Router({ caseSensitive: true, strict: true });
router.get('/events', function (req, res) {
res.send('events');
});
// mount the router on an app
app.use('/calendar', router);

router.all()

Argumentos

path
Tipo: String | RegExp | Array

La ruta para la cual se invocan los callbacks de ruta.

callback
Tipo: Function | Function[]

Una o más funciones middleware/manejadoras. Cada una puede llamar a next('route') para saltar los callbacks restantes.

Este método es igual a los métodos router.METHOD(), excepto que coincide con todos los métodos HTTP (verbos).

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

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

O el equivalente:

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

Otro ejemplo de esto es la funcionalidad “global” con lista blanca. Aquí el ejemplo es muy similar al anterior, pero solo restringe las rutas con prefijo “/api”:

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

router.METHOD()

Argumentos

path
Tipo: String | RegExp | Array

La ruta para la cual se invocan los callbacks de ruta.

callback
Tipo: Function | Function[]

Una o más funciones middleware/manejadoras. Cada una puede llamar a next('route') para saltar los callbacks restantes.

Los métodos router.METHOD() proporcionan la funcionalidad de enrutamiento en Express, donde METHOD es uno de los métodos HTTP, como GET, PUT, POST, etc., en minúsculas. Por lo tanto, los métodos reales son router.get(), router.post(), router.put(), etc.

Nota

La función router.get() se llama automáticamente para el método HTTP HEAD además del método GET si router.head() no fue llamado para la ruta antes de router.get().

Nota

router.query() enruta peticiones HTTP QUERY, reflejando app.query(). El método QUERY está controlado por el runtime y requiere Node.js >=20.19.3 <21 || >=22.2.0.

Puedes proporcionar múltiples callbacks, y todos son tratados por igual, y se comportan como middleware, excepto que estos callbacks pueden invocar next('route') para omitir los callbacks de ruta restantes. Puedes usar este mecanismo para realizar pre-condiciones en una ruta y luego pasar el control a las rutas subsiguientes cuando no haya razón para continuar con la ruta coincidente.

El siguiente fragmento ilustra la definición de ruta más simple posible. Express traduce los strings de ruta a expresiones regulares, usadas internamente para coincidir con las peticiones entrantes. Los query strings no se consideran al realizar estas coincidencias, por ejemplo “GET /” coincidiría con la siguiente ruta, al igual que “GET /?name=tobi”.

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

También puedes usar expresiones regulares — útil si tienes restricciones muy específicas, por ejemplo lo siguiente coincidiría con “GET /commits/71dbb9c” así como con “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.param()

Argumentos

name
Tipo: String

El nombre del parámetro de ruta al que adjuntar el trigger. A diferencia de app.param(), esto no acepta un array.

callback
Tipo: Function

El trigger llamado como callback(req, res, next, value, name).

Añade callbacks triggers a los parámetros de ruta, donde name es el nombre del parámetro y callback es la función de callback. Aunque name es técnicamente opcional, usar este método sin él está obsoleto desde Express v4.11.0 (ver abajo).

Los parámetros de la función de callback son:

  • req, el objeto de petición.
  • res, el objeto de respuesta.
  • next, indicando la siguiente función middleware.
  • El valor del parámetro name.
  • El nombre del parámetro.

Nota

A diferencia de app.param(), router.param() no acepta un array de parámetros de ruta.

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

router.param('user', function (req, res, next, id) {
// try to get the user details from the User model and attach it to the request object
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'));
}
});
});

Las funciones de callback de parámetros son locales al router en el que se definen. No son heredadas por apps o routers montados, ni se activan para parámetros de ruta heredados de routers padre. Por lo tanto, los callbacks de parámetros definidos en router solo se activarán por parámetros de ruta definidos en las rutas de router.

Un callback de parámetro se llamará solo una vez en un ciclo petición-respuesta, incluso si el parámetro coincide en múltiples rutas, como se muestra en los siguientes ejemplos.

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

En GET /user/42, se imprime lo siguiente:

CALLED ONLY ONCE
although this matches
and this matches too

Precaución

La siguiente sección describe router.param(callback), que está obsoleto desde v4.11.0.

El comportamiento del método router.param(name, callback) puede alterarse por completo pasando solo una función a router.param(). Esta función es una implementación personalizada de cómo router.param(name, callback) debería comportarse — acepta dos parámetros y debe devolver un middleware.

El primer parámetro de esta función es el nombre del parámetro URL que se debe capturar, el segundo parámetro puede ser cualquier objeto JavaScript que se pueda usar para devolver la implementación del middleware.

El middleware devuelto por la función decide el comportamiento de lo que ocurre cuando se captura un parámetro URL.

En este ejemplo, la firma router.param(name, callback) se modifica a router.param(name, accessId). En lugar de aceptar un nombre y un callback, router.param() ahora aceptará un nombre y un número.

index.cjs
var express = require('express');
var app = express();
var router = express.Router();
// customizing the behavior of router.param()
router.param(function (param, option) {
return function (req, res, next, val) {
if (val === option) {
next();
} else {
res.sendStatus(403);
}
};
});
// using the customized router.param()
router.param('id', '1337');
// route to trigger the capture
router.get('/user/:id', function (req, res) {
res.send('OK');
});
app.use(router);
app.listen(3000, function () {
console.log('Ready');
});

En este ejemplo, la firma router.param(name, callback) permanece igual, pero en lugar de un callback middleware, se ha definido una función personalizada de comprobación de tipo de datos para validar el tipo de datos del id de usuario.

router.param(function (param, validator) {
return function (req, res, next, val) {
if (validator(val)) {
next();
} else {
res.sendStatus(403);
}
};
});
router.param('id', function (candidate) {
return !isNaN(parseFloat(candidate)) && isFinite(candidate);
});

router.route()

Argumentos

path
Tipo: String

La ruta de la ruta a crear.

Devuelve una instancia de una sola ruta que puedes usar luego para manejar verbos HTTP con middleware opcional. Usa router.route() para evitar la duplicación de nombres de ruta y así errores de escritura.

Basándose en el ejemplo de router.param() anterior, el siguiente código muestra cómo usar router.route() para especificar varios manejadores de métodos HTTP.

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!
next();
})
.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'));
});

Este enfoque reutiliza la única ruta /users/:user_id y añade manejadores para varios métodos HTTP.

Nota

Cuando usas router.route(), el orden del middleware se basa en cuándo se crea la route, no en cuándo se añaden los manejadores de método a la ruta. Para este propósito, puedes considerar que los manejadores de método pertenecen a la ruta a la que fueron añadidos.

router.use()

Argumentos

path
Tipo: String | RegExp | Array | undefined

La ruta de montaje para el middleware. Por defecto es /.

callback
Tipo: Function | Function[]

Una o más funciones middleware a montar.

Usa la función o funciones middleware especificadas, con ruta de montaje opcional path, que por defecto es ”/”.

Este método es similar a app.use(). Un ejemplo simple y caso de uso se describe abajo. Consulta app.use() para más información.

El middleware es como una tubería de plomería: las peticiones empiezan en la primera función middleware definida y van bajando por la pila de middleware procesando cada ruta que coinciden.

index.cjs
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);

La ruta de “montaje” se elimina y no es visible para la función middleware. El efecto principal de esta característica es que una función middleware montada puede operar sin cambios de código independientemente de su nombre de ruta de “prefijo”.

El orden en que defines middleware con router.use() es muy importante. Se invocan secuencialmente, por lo tanto el orden define la precedencia del middleware. Por ejemplo, normalmente un logger es el primer middleware que usarías, para que cada petición quede registrada.

index.cjs
var logger = require('morgan');
var path = require('path');
router.use(logger());
router.use(express.static(path.join(__dirname, 'public')));
router.use(function (req, res) {
res.send('Hello');
});

Ahora supón que quisieras ignorar el registro de peticiones para archivos estáticos, pero continuar registrando rutas y middleware definidos después de logger(). Simplemente moverías la llamada a express.static() al principio, antes de añadir el middleware logger:

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

Otro ejemplo es servir archivos desde múltiples directorios, dando precedencia a ”./public” sobre los demás:

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

El método router.use() también soporta parámetros nombrados para que tus puntos de montaje para otros routers puedan beneficiarse de la precarga usando parámetros nombrados.

Nota

Aunque estas funciones middleware se añaden vía un router particular, cuándo se ejecutan se define por la ruta a la que están adjuntas (no el router). Por lo tanto, el middleware añadido vía un router puede ejecutarse para otros routers si sus rutas coinciden.

Por ejemplo, este código muestra dos routers diferentes montados en la misma ruta:

var authRouter = express.Router();
var openRouter = express.Router();
authRouter.use(require('./authenticate').basic(usersdb));
authRouter.get('/:user_id/edit', function (req, res, next) {
// ... Edit user UI ...
});
openRouter.get('/', function (req, res, next) {
// ... List users ...
});
openRouter.get('/:user_id', function (req, res, next) {
// ... View user ...
});
app.use('/users', authRouter);
app.use('/users', openRouter);

A pesar de que el middleware de autenticación se añadió vía el authRouter se ejecutará también en las rutas definidas por el openRouter ya que ambos routers estaban montados en /users. Para evitar este comportamiento, usa rutas diferentes para cada router.