Enrutamiento
El enrutamiento se refiere a cómo los endpoints de una aplicación (URIs) responden a las solicitudes de los clientes. Para una introducción al enrutamiento, consulta Enrutamiento básico.
Defines el enrutamiento usando métodos del objeto app de Express que corresponden a los métodos HTTP;
por ejemplo, app.get() para manejar solicitudes GET y app.post para manejar solicitudes POST. Para una lista completa,
consulta app.METHOD. También puedes usar app.all() para manejar todos los métodos HTTP y app.use() para
especificar middleware como función de callback (consulta Uso de middleware para más detalles).
Estos métodos de enrutamiento especifican una función de callback (a veces llamada "función manejadora") que Express ejecuta automáticamente cuando la aplicación recibe una solicitud que coincide con la ruta (endpoint) y el método HTTP especificados. En otras palabras, la aplicación "escucha" las solicitudes que coinciden con las rutas y métodos especificados, y cuando detecta una coincidencia, llama a la función de callback especificada.
De hecho, los métodos de enrutamiento pueden tener más de una función de callback como argumentos.
Con múltiples funciones de callback, es importante proporcionar next como argumento a la función de callback y luego llamar a next() dentro del cuerpo de la función para pasar el control
al siguiente callback.
El siguiente código es un ejemplo de una ruta muy básica.
const express = require('express');const app = express();
// respond with "hello world" when a GET request is made to the homepageapp.get('/', (req, res) => { res.send('hello world');});import express from 'express';
const app = express();
// respond with "hello world" when a GET request is made to the homepageapp.get('/', (req, res) => { res.send('hello world');});Métodos de ruta
Un método de ruta se deriva de uno de los métodos HTTP, y se adjunta a una instancia de la clase express.
El siguiente código es un ejemplo de rutas que se definen para los métodos GET y POST hacia la raíz de la aplicación.
// GET method routeapp.get('/', (req, res) => { res.send('GET request to the homepage');});
// POST method routeapp.post('/', (req, res) => { res.send('POST request to the homepage');});Express soporta métodos que corresponden a todos los métodos de solicitud HTTP: get, post, y así sucesivamente.
Para una lista completa, consulta app.METHOD.
Hay un método de enrutamiento especial, app.all(), usado para cargar funciones de middleware en una ruta para todos los métodos de solicitud HTTP. Por ejemplo, el siguiente manejador se ejecuta para solicitudes a la ruta "/secret" ya sea usando GET, QUERY, POST, PUT, DELETE, o cualquier otro método de solicitud HTTP soportado en el módulo http.
app.all('/secret', (req, res, next) => { console.log('Accessing the secret section ...'); next(); // pass control to the next handler});Rutas de ruta
Las rutas de ruta, en combinación con un método de solicitud, definen los endpoints en los que se pueden hacer solicitudes. Las rutas de ruta pueden ser cadenas, patrones de cadena, o expresiones regulares.
Nota
Express usa path-to-regexp para coincidir las rutas de ruta; consulta la documentación de path-to-regexp para todas las posibilidades al definir rutas de ruta. Express Playground Router es una herramienta útil para probar rutas básicas de Express, aunque no soporta la coincidencia de patrones.
Rutas de ruta basadas en cadenas
Advertencia
Esta ruta de ruta coincidirá con solicitudes a la ruta raíz, /.
app.get('/', (req, res) => { res.send('root');});Esta ruta de ruta coincidirá con solicitudes a /about.
app.get('/about', (req, res) => { res.send('about');});Esta ruta de ruta coincidirá con solicitudes a /random.text.
app.get('/random.text', (req, res) => { res.send('random.text');});Rutas de ruta basadas en patrones de cadena
Esta ruta de ruta coincidirá con acd y abcd.
app.get('/ab?cd', (req, res) => { res.send('ab?cd');});Esta ruta de ruta coincidirá con abcd, abbcd, abbbcd, y así sucesivamente.
app.get('/ab+cd', (req, res) => { res.send('ab+cd');});Esta ruta de ruta coincidirá con abcd, abxcd, abRANDOMcd, ab123cd, y así sucesivamente.
app.get('/ab*cd', (req, res) => { res.send('ab*cd');});Esta ruta de ruta coincidirá con /abe y /abcde.
app.get('/ab(cd)?e', (req, res) => { res.send('ab(cd)?e');});Rutas de ruta basadas en expresiones regulares
Precaución
Los caracteres de expresiones regulares como $ necesitan escaparse con un \.
Esta ruta de ruta coincidirá con cualquier cosa que contenga una "a".
app.get(/a/, (req, res) => { res.send('/a/');});Esta ruta de ruta coincidirá con butterfly y dragonfly, pero no con butterflyman, dragonflyman, y así sucesivamente.
app.get(/.*fly$/, (req, res) => { res.send('/.*fly$/');});Parámetros de ruta
Los parámetros de ruta son segmentos de URL nombrados que se usan para capturar los valores especificados en su posición dentro de la URL. Los valores capturados se populan en el objeto req.params, con el nombre del parámetro de ruta especificado en la ruta como sus respectivas claves.
Route path: /users/:userId/books/:bookIdRequest URL: http://localhost:3000/users/34/books/8989req.params: { "userId": "34", "bookId": "8989" }Para definir rutas con parámetros de ruta, simplemente especifica los parámetros de ruta en la ruta de la ruta como se muestra a continuación.
app.get('/users/:userId/books/:bookId', (req, res) => { res.send(req.params);});Precaución
El nombre de los parámetros de ruta debe estar compuesto por "caracteres de palabra" ([A-Za-z0-9_]).
Dado que el guion (-) y el punto (.) se interpretan literalmente, pueden usarse junto con los parámetros de ruta para propósitos útiles.
Route path: /flights/:from-:toRequest URL: http://localhost:3000/flights/LAX-SFOreq.params: { "from": "LAX", "to": "SFO" }Route path: /plantae/:genus.:speciesRequest URL: http://localhost:3000/plantae/Prunus.persicareq.params: { "genus": "Prunus", "species": "persica" }Para tener más control sobre la cadena exacta que puede coincidir con un parámetro de ruta, puedes añadir una expresión regular entre paréntesis (()):
Route path: /user/:userId(\d+)Request URL: http://localhost:3000/user/42req.params: {"userId": "42"}Advertencia
Como la expresión regular suele ser parte de una cadena literal, asegúrate de escapar cualquier carácter \
con una barra invertida adicional, por ejemplo \\d+.
Advertencia
El carácter * en las expresiones regulares no se interpreta de la forma habitual. Como alternativa, usa {0,} en lugar de *.
Manejadores de ruta
Puedes proporcionar múltiples funciones de callback que se comportan como middleware para manejar una solicitud. La única excepción es que estos callbacks pueden invocar next('route') para omitir los callbacks de ruta restantes. Puedes usar este mecanismo para imponer pre-condiciones en una ruta, y luego pasar el control a las rutas subsiguientes si no hay razón para continuar con la ruta actual.
app.get('/user/:id', (req, res, next) => { if (req.params.id === '0') { return next('route'); } res.send(`User ${req.params.id}`);});
app.get('/user/:id', (req, res) => { res.send('Special handler for user ID 0');});En este ejemplo:
GET /user/5→ manejado por la primera ruta → envía "User 5"GET /user/0→ la primera ruta llama anext('route'), saltando a la siguiente ruta que coincide con/user/:id
Los manejadores de ruta pueden tener la forma de una función, un array de funciones, o combinaciones de ambas, como se muestra en los siguientes ejemplos.
Una sola función de callback puede manejar una ruta. Por ejemplo:
app.get('/example/a', (req, res) => { res.send('Hello from A!');});Más de una función de callback puede manejar una ruta (asegúrate de especificar el objeto next). Por ejemplo:
app.get( '/example/b', (req, res, next) => { console.log('the response will be sent by the next function ...'); next(); }, (req, res) => { res.send('Hello from B!'); });Un array de funciones de callback puede manejar una ruta. Por ejemplo:
const cb0 = function (req, res, next) { console.log('CB0'); next();};
const cb1 = function (req, res, next) { console.log('CB1'); next();};
const cb2 = function (req, res) { res.send('Hello from C!');};
app.get('/example/c', [cb0, cb1, cb2]);Una combinación de funciones independientes y arrays de funciones puede manejar una ruta. Por ejemplo:
const cb0 = function (req, res, next) { console.log('CB0'); next();};
const cb1 = function (req, res, next) { console.log('CB1'); next();};
app.get( '/example/d', [cb0, cb1], (req, res, next) => { console.log('the response will be sent by the next function ...'); next(); }, (req, res) => { res.send('Hello from D!'); });Métodos de respuesta
Los métodos del objeto de respuesta (res) en la siguiente tabla pueden enviar una respuesta al cliente y terminar el ciclo solicitud-respuesta. Si ninguno de estos métodos es llamado desde un manejador de ruta, la solicitud del cliente quedará colgada.
| Método | Descripción |
|---|---|
| res.download() | Provoca la descarga de un archivo. |
| res.end() | Finaliza el proceso de respuesta. |
| res.json() | Envía una respuesta JSON. |
| res.jsonp() | Envía una respuesta JSON con soporte JSONP. |
| res.redirect() | Redirige una solicitud. |
| res.render() | Renderiza una plantilla de vista. |
| res.send() | Envía una respuesta de varios tipos. |
| res.sendFile() | Envía un archivo como un flujo octet. |
| res.sendStatus() | Establece el código de estado de la respuesta y envía su representación en cadena como cuerpo de la respuesta. |
app.route()
Puedes crear manejadores de ruta encadenables para una ruta de ruta usando app.route().
Como la ruta se especifica en una sola ubicación, crear rutas modulares es útil, ya que reduce la redundancia y los errores tipográficos. Para más información sobre rutas, consulta: documentación de Router().
Aquí hay un ejemplo de manejadores de ruta encadenados que se definen usando app.route().
app .route('/book') .get((req, res) => { res.send('Get a random book'); }) .post((req, res) => { res.send('Add a book'); }) .put((req, res) => { res.send('Update the book'); });express.Router
Usa la clase express.Router para crear manejadores de ruta modulares y montables. Una instancia de Router es un sistema completo de middleware y enrutamiento; por esta razón, a menudo se le llama "mini-app".
El siguiente ejemplo crea un router como módulo, carga una función de middleware en él, define algunas rutas, y monta el módulo router en una ruta en la aplicación principal.
Crea un archivo de router llamado birds.js en el directorio de la aplicación, con el siguiente contenido:
const express = require('express');const router = express.Router();
// middleware that is specific to this routerconst timeLog = (req, res, next) => { console.log('Time: ', Date.now()); next();};router.use(timeLog);
// define the home page routerouter.get('/', (req, res) => { res.send('Birds home page');});// define the about routerouter.get('/about', (req, res) => { res.send('About birds');});
module.exports = router;import express from 'express';
const router = express.Router();
// middleware that is specific to this routerconst timeLog = (req, res, next) => { console.log('Time: ', Date.now()); next();};router.use(timeLog);
// define the home page routerouter.get('/', (req, res) => { res.send('Birds home page');});// define the about routerouter.get('/about', (req, res) => { res.send('About birds');});
export default router;Luego, carga el módulo router en la aplicación:
const birds = require('./birds');
// ...
app.use('/birds', birds);import birds from './birds';
// ...
app.use('/birds', birds);La aplicación ahora podrá manejar solicitudes a /birds y /birds/about, así como llamar a la función de middleware timeLog que es específica de la ruta.
Pero si la ruta padre /birds tiene parámetros de ruta, no será accesible por defecto desde las sub-rutas. Para hacerla accesible, necesitarás pasar la opción mergeParams al constructor de Router referencia.
const router = express.Router({ mergeParams: true });