routing

El enrutamiento se refiere a cómo una aplicación express responde a las solicitudes de los clientes. Se utilizan los métodos de la aplicación app.METHOD y app.use que además del path al que responden, especifican una o varias funciones de callback que se ejecutan cada vez que se recibe una solicitud para el path indicado. Si se especifican varias funciones de callback se deben ejecutar las funciones next para que la ejecución pase a la siguiente, como ya se ha visto anteriormente.

Los paths incluidos como primer argumento en los métodos de ruta pueden ser cadenas, patrones de cadenas o expresiones regulares.

En los patrones de cadena se pueden utilizar los siguientes caracteres comodín:

Por ejemplo:

app.get('/ab*cd', function (req, res) {
   console.log(“sirve a path /abcd, a /abdsscd o a /abs34asdacd”);
})
                 
app.get('/ab+cd', function (req, res) {
   console.log(“no sirve a path /abcd pero si a /abdsscd o a /abs34asdacd”);
})

app.get('/ab?cd', function (req, res) {
   console.log(“sirve a path /abcd, a /acd pero no sirve a /abdsscd o a /abs34asdacd”);
})

app.get('/ab(sx)?cd', function (req, res) {
   console.log(“sirve a path /abcd, a /absxcd  pero no a /absxasdacd”);
})
            

En los path de ruta se pueden especificar lo que se denominan parámetros de ruta. Con un ejemplo se ve mejor: Si el path en un método app.get es /datos/:usuario/ficha/:libro, y la petición de un cliente fuera a la dirección /datos/pepe/ficha/quijote entonces en la función de callback tendríamos acceso al nombre del usuario a través de req.params.usuario, que sería pepe y al libro a través de req.params.libro que sería quijote. Los parámetros de ruta se incorporan al path precediendo el nombre del parámetro de dos puntos. Para tener más control sobre la cadena exacta que puede coincidir con un parámetro de ruta, se puede agregar una expresión regular entre paréntesis ():

app.get(“/datos/:id(\\d+)

Solo coincidiría con rutas en la que el id solo contuviera números.

Las funciones de callback pueden terminar enviando la respuesta al cliente, o pueden encadenarse con el siguiente middelware si terminan ejecutando la función next().

Los métodos del objeto response de la siguiente tabla envían una respuesta al cliente y terminan el ciclo de solicitud-respuesta. Si ninguno de estos métodos se llama desde la función de callback, ni se ejecuta la función next(), la solicitud del cliente quedará pendiente y en el navegador del cliente se mostrará el mensaje de error de tiempo excedido.

Podemos modularizar la respuesta a peticiones haciendo uso de la clase Router de la clase express.

Con un ejemplo se verá. Tengamos un archivo de módulo con nombre libros.js con el siguiente contenido:

const router = require("express").Router();

router.get('/', function(req, res) {
    res.send('Página home de libros')
    })

router.get('/about', function(req, res) {
    res.send('Acerca de libros')
})

module.exports = router

Y en index.js hacemos uso de él.

const libros = require("./libros");
const app = require('express')();

app.get("/", (req, res, next) => {
    res.send("Home");
});

app.use("/libros", libros); // atenderá peticiones para /libros/ y para /libros/about

app.use((req, res, next) => {
    res.send(404,"recurso no encontrado"); // termina
});

app.listen(8080, () => {
    console.log('servidor funcionando en puerto 8080');
})
            

Hemos separado, modularizado, las peticiones para todas las rutas bajo /libros a un archivo separado. Esto hace el código más estructurado, más legible y más fácil de mantener.

e-mail:manjarrés