Mi primera aplicación con Express.js III. Las rutas


En el artículo anterior te expliqué la estructura que crea el framework Express.js así como sus archivos fundamentales, con el objetivo de garantizar un punto de partida para poder comenzar a desarrollar aplicaciones. En el artículo de hoy profundizaré, mediante una serie de ejemplos, la definición de rutas.

Estaré trabajando en lo adelante sobre la aplicación que creé en el primer artículo de este curso. Manos a la obra.

Las rutas

Las rutas nos permiten direccionar peticiones a los controladores correctos. Anteriormente expliqué que las rutas se definen por defecto en el archivo app.js que se encuentra en la raíz del proyecto a través de la instrucción:

app.<method>(<ruta>,<controlador_asociado>)

Como puedes observar, se utiliza la variable que almacena nuestra aplicación express y se llama al método con el cual se desea capturar la ruta (los métodos pueden ser GET, POST y PUT), pasándole a este la ruta que queramos definir y la función que se asociará a esta ruta, o sea, el controlador asociado.

Ejemplo 1: Establecer una respuesta para la ruta “/hola”

app.get("/hola", function(req, res){

     res.writeHead({"Content-Type":"text/html"});

     res.write("Hola Mundo !!!");

     res.end();

});

Como ves, se escoge el método a utilizar, en este caso GET, luego se define la ruta que se pretende crear y por último se define el controlador que será encargado de responder cuando se haga una petición a esta ruta. En el ejemplo anterior el controlador únicamente responderá con el texto Hola Mundo !!!. Para poder ver este ejemplo en funcionamiento vamos al archivo app.js de nuestro proyecto y copiamos el código anterior como se muestra en la imagen siguiente:

Fragmento del archivo app.js

Fig.1 Fragmento del archivo app.js

Es importante el orden en que se ubican las rutas, debido a que cuando el framework encuentra una coincidencia deja de buscar y esto puede ocasionar que una ruta definida en la posición incorrecta nunca sea analizada. Luego de guardar los cambios realizados al archivo app.js podemos probar la ruta recién creada, para ello vamos a utilizar el comando siguiente:

curl http://localhost:3000/hola

Con esto debe mostrarse en pantalla la respuesta del servidor, tal como se muestra a continuación:

Resultado del comando curl.

Fig.2 Resultado del comando curl.

Ejemplo 2: Definir una ruta dinámica

Ahora imagina que nuestra aplicación maneja artículos, por lo que definimos lo siguiente:

app.get('/article/:id?', function(req,res){
  res.writeHead(200, {"Content-Type":"text/html"});
  var article = req.params.id ? 'Found: '+req.params.id : "Empty";
  res.write(article+'\n');
  res.end();
});

Esto permite al servidor responder tanto a un GET de /articles como a /articles/12 o /articles/pepe, y esto es posible porque el primer parámetro de la función GET es utilizado por Express como una expresión regular, por lo cual esta definición puede servir para listar todos los artículos o el artículo que se solicite a través del valor de id. Y esto es posible porque id define un placeholder lo cual nos permite acceder a su valor a través del objeto req.params.

También podemos definir varios placeholders, debajo un ejemplo:

app.get('/controller/:id/:action', function(req,res){
  res.writeHead(200, {"Content-Type":"text/html"});
  var article = 'Controller '+req.params.id + ' with action '+    req.params.action;
  res.write(article+'\n');
  res.end();
});

Y si bien esto es resulta extremadamente útil, puedes hacer cosas más complejas, como por ejemplo:

app.get('/article/:id([0-9]+)/:action(edit|delete|create)', function(req,res){
  res.writeHead(200, {"Content-Type":"text/html"});
  res.write(' Parameters: \n');
  for(key in req.params){
    res.write(key+' : '+req.params[key]+'\n');
  }
  res.end();
});

Y como puedes observar, aquí no sólo accedemos a id y action, sino que restringimos el primero a que sea numérico y damos tres opciones para el segundo, gracias al poder de las expresiones regulares.

Ejemplo 3: Obteniendo datos de una petición POST

Luego de analizar cómo definir rutas a través del método GET, ahora te enseñaré cómo definir rutas con POST y cómo capturar los datos enviados, para ello observa el siguiente código:

app.post('/articles', function(req,res){
  res.writeHead(200, {"Content-Type":"text/html"});
  res.write('Parameters: \n');
  for(key in req.body){
    res.write(key+' : '+req.body[key]+'\n');
  }
  res.end();
});

Como puedes observar la definición no cambia con respecto a las vistas anteriormente, excepto por el hecho de que aquí se escoge el método POST. Para obtener los datos nos valemos del middleware bodyParser que nos permite acceder a los valores pasados a través del objeto req.body. Debajo te muestro la respuesta del servidor al realizar una petición a esta ruta:

Resultado del comando curl para una petición POST.

Fig3. Resultado del comando curl para una petición POST.

Ejemplo 4: Manejar errores del tipo 404

Para el manejo de los errores producidos al tratar de acceder a una ruta no definida, puedes utilizar el siguiente código:

app.all('*', function(req,res){
  res.writeHead(404, {"Content-Type":"text/html"});
  res.write('Page not found !!!\n');
  res.end();
});

Como puedes observar se utiliza all en lugar de utilizar un método para capturar la petición por cualquiera de ellos y se define la ruta con la expresión regular *, para que cualquier ruta sea capturada. Este código debe ir al final, por lo que te expliqué de la importancia del orden en que se definen las rutas.

Conclusiones

En este artículo te mostré, a través de una serie de ejemplos, cómo definir y trabajar con las rutas en el framework Espress.js y pudiste observar las facilidades que brinda el framework a la hora de definir las rutas de una aplicación.

Espero te sea de ayuda este tutorial en tus proyectos, y cualquier duda o sugerencia estaré feliz de responderlas en los comentarios. Happy Coding!!!