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, en combinación con un método de petición, definen los endpoints en los que se pueden hacer peticiones. Las rutas pueden ser strings o expresiones regulares.
Nota
Express usa path-to-regexp v8 para hacer coincidir las rutas; consulta la documentación de path-to-regexp para todas las posibilidades en la definición de rutas. Express Playground Router es una herramienta útil para probar rutas básicas de Express, aunque no soporta la coincidencia de patrones.
Rutas de string
Las rutas de string coinciden con las peticiones exactamente. El punto (.) y el guion (-) se interpretan literalmente.
Advertencia
app.get('/', (req, res) => { res.send('root');});
app.get('/about', (req, res) => { res.send('about');});
app.get('/random.text', (req, res) => { res.send('random.text');});Comodines
Los comodines coinciden con cualquier ruta después de un prefijo. Deben tener un nombre, al igual que los parámetros de ruta, y se capturan como arrays de segmentos de ruta.
app.get('/files/*filepath', (req, res) => { // GET /files/images/logo.png console.dir(req.params.filepath); // => [ 'images', 'logo.png' ] res.send(`File: ${req.params.filepath.join('/')}`);});Para coincidir también con la ruta raíz, envuelve el comodín en llaves:
// Matches / , /foo , /foo/bar , etc.app.get('/{*splat}', (req, res) => { // GET / => req.params.splat = [] // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] res.send('ok');});Segmentos opcionales
Usa llaves para definir segmentos opcionales en una ruta. Cuando el segmento no está presente, el parámetro se omite de req.params.
app.get('/:file{.:ext}', (req, res) => { // GET /image.png => req.params = { file: 'image', ext: 'png' } // GET /image => req.params = { file: 'image' } res.send('ok');});Precaución
Los caracteres ?, +, *, [], y () están reservados y no pueden usarse como caracteres literales en las rutas. Usa \ para escaparlos si es necesario.
Expresiones regulares
También puedes usar expresiones regulares como rutas. Esto es útil cuando necesitas una lógica de coincidencia más compleja.
// Matches any path containing "a"app.get(/a/, (req, res) => { res.send('/a/');});
// Matches paths ending with "fly" (butterfly, dragonfly, etc.)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" }Precaución
Los caracteres de expresiones regulares no son soportados en las rutas. Usa un array de rutas o expresiones regulares en su lugar. Consulta la sintaxis de coincidencia de rutas para más información.
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 });