Routing con NodeJS

Una URL, por lo general, se compone de muchas partes. Cada una cumple un prop贸sito y una funci贸n especifica; un desarrollador Back-End, tiene que poder diferenciar dichas secciones, de modo tal, que pueda lograr interpretar, mediante su c贸digo, que es lo que tiene que realizar su aplicaci贸n dependiendo de la url que solicite el cliente, esto se llama routing.

Imaginemos una URL basica, por ejemplo, la pagina de mi emprendimiento personal, Wildevs:

https://wildevs.com/

Esta URL es muy sencilla, consta del protocolo de comunicaci贸n https, el dominio wildevs, y finalmente, de una extensi贸n de dominio, en esta caso com.
Existen ocasiones en las cuales la URL se torna un c贸digo apelmazado inentendible a simple vista, no obstante, toda URL respeta una "sintaxis" b谩sica:

Sintaxis de URL

Imaginemos por un momento la siguiente situaci贸n: nuestra app, cuenta con una api que nos da acceso a una base de datos en donde se encuentran almacenados los clientes de nuestra empresa, y que a su vez, cada cliente tiene proyectos asociados. Realmente, en este punto, no importa la estructura de la base de datos, sino, como se realizar铆a la consulta de dicha informaci贸n.

Al momento de realizar la petici贸n de dicha informaci贸n, el link seria muy parecido a este:

                               url.parse(string).query
                                         |
           url.parse(string).pathname    |
                 |                       |
                 |                       |
                --- ---------------------------------
https://wildevs/api?cliente=high&proyecto=productions  
                    -------               -----------
                       |                       |
                       |                       |
        querystring(string)["cliente"]         |
                                               |
                     querystring(string)["productions"]

Como se puede observar, una URL se compone de muchos otros componentes que un usuario normal no tiene por que conocer, pero que un desarrollador Back-End debe conocerlos y poderlos manipular en profundidad.

No voy a explicar para que sirve cada parte de una URL, pero en este articulo de la wikipedia se explica bastante bien. 馃槑

Ense帽ar a Node a leer URLs.

El "hazlo tu mismo", es parte indiscutible del desarrollo sobre NodeJS, y la interpretaci贸n de URLs no es la excepci贸n.
Quiz谩, esta tarea se podr铆a simplificar enormemente utilizando, por ejemplo, express, koa o cualquier otro framework de node, pero de ese modo no seria divertido(? 馃槰

Vamos a utilizar un objeto de Node llamado url, el cual nos va a permitir poder interpretar URLs.

En nuestro archivo server.js, importamos dicho modulo:

import url from 'url'  

Un uso b谩sico del modulo URL, es permitirle a nuestro peque帽o servidor el interpretar las distintas rutas solicitadas; para ello, crearemos una variable que guardara el pathname, o subdirecci贸n, de nuestra URL:

let pathname = url.parse(req.url).pathname  

Esto es f谩cil de realizar, utilizando el m茅todo parse() del objeto URL, y pasando como par谩metro la informaci贸n de la URL contenida en nuestro objeto req.

Para probar que todo funciona correctamente, podemos agregar un mensaje con console.log() que informe el path solicitado:

console.log(`Solicitud recibida para: ${pathname}`)  

El c贸digo de nuestro archivo server.js, quedar铆a algo as铆:

import http from 'http'  
import url from 'url'

import config from './config'

exports.startServer = () => {  
    const onRequest = (req, res) => {
        let pathName = url.parse(req.url).pathname
        console.log(`Peticion recibida para: ${pathName}`)

        res.writeHead(200, { 'Content-Type': 'text/html' })
        res.write('Hola Mundo')
        res.end()
    }

    http.createServer(onRequest).listen(config.port)

    console.log('El servidor esta corriendo en el puerto: ' + config.port)
}

Al probar, por ejemplo, las siguientes direcciones, localhost:3000/hola, o localhost:3000/ke, obtenemos la siguiente respuesta en el log:

Como hable en el post anterior, siempre tenemos que tratar de que nuestra aplicaci贸n sea lo mas modular posible, por lo tanto vamos a crear nuestro enrutador, el cual en un principio no va hacer mucho, pero contribuye a contener la modularizaci贸n.

Creamos un archivo router.js, el cual contendr谩 el siguiente c贸digo:

exports.route = (pathname) => {  
    console.log('Solicitud sobre ruta: ' + pathname)
}

Tenemos que tambi茅n, importar este modulo en nuestro app.js, y enviar por par谩metro la funci贸n "route" en la funci贸n startServer()

Finalmente, en nuestro archivo server.js, la funci贸n startServer(), se inicializara con un par谩metro "route", y dentro del cuerpo la funci贸n onRequest() podemos llamar al m茅todo route().

El codigo del archivo server.js, borrando el comentario de log, seria el siguiente:

import http from 'http'  
import url from 'url'

import config from './config'

exports.startServer = (route) => {  
    const onRequest = (req, res) => {
        let pathname = url.parse(req.url).pathname

        route(pathname)

        res.writeHead(200, { 'Content-Type': 'text/html' })
        res.write('Hola Mundo')
        res.end()
    }

    http.createServer(onRequest).listen(config.port)

    console.log('El servidor esta corriendo en el puerto: ' + config.port)
}

Si probamos nuevamente nuestra app en el explorador, obtenemos el mismo resultado.

Con esto, basta para que nuestro servidor pueda discrepar entre distintas rutas, pero no para que reaccione ante ellas. Actualmente, lanzamos un mensaje de log con el nombre de la ruta solicitado, no importa cual sea dicha ruta, el servidor no hace otra cosa que mostrar ese mensaje de log.
Claro, se podr铆a agregar una estructura de control estilo switch y comprar el path que llega, realizando una acci贸n dependiendo del resultado, pero esto seria realmente feo y poco escalable.

Lo que tenemos que hacer, es construir nuestros propios manejadores (Handlers) de solicitudes. Pero bueno, eso queda para otra publicaci贸n.

El c贸digo de este ejemplo, se encuentra en mi GitHub, en el siguiente link.

Hasta la pr贸xima!

Show Comments

Get the latest posts delivered right to your inbox.