2 Express¶
Introducción¶
Existen diferente librerías y frameworks para poder diseñar una aplicación REST API en Node JS, además de la forma nativa ya vista en el tema anterior. Entre ellas encontramos:
- Restify: Es un framework específicamente diseñado para construir APIs Restful en Node JS. Está optimizado para el rendimiento y tiene funcionalidades incorporadas para la validación, versionado y manejo de errores en APIs.
- Hapi.js: Es un framework que se utiliza para construir aplicaciones y servicios en Node.js. Al igual que Express, Hapi.js es versátil y se puede utilizar para crear APIs RESTful. Proporciona una arquitectura modular y extensible.
- Koa.js: Desarrollado por el equipo detrás de Express.js, Koa.js es un framework más nuevo y más ligero. Aunque no es específicamente un framework para APIs REST, su enfoque modular y su sistema de middleware lo hacen adecuado para construir APIs.
- Nest.js: Es un framework más completo y basado en TypeScript que utiliza las mejores prácticas de desarrollo y arquitectura. Está construido sobre Express.js y proporciona una estructura modular basada en módulos, inyección de dependencias y decoradores.
En este tema se trabajara con Express
Express¶
Express.js, comúnmente conocido como Express, es un framework web para Node.js que facilita la creación de aplicaciones web y APIs. Es minimalista, flexible y está diseñado para ser una capa ligera sobre Node.js, proporcionando una serie de características y herramientas que simplifican el desarrollo web.
Algunas características clave de Express incluyen:
- Enrutamiento: Express simplifica el manejo de las rutas y las solicitudes HTTP. Puedes definir rutas y especificar cómo deben manejarse las solicitudes para esas rutas.
- Middleware: Express utiliza un sistema de middleware que te permite ejecutar funciones en el ciclo de vida de una solicitud. Esto es útil para realizar tareas como la autenticación, la manipulación de datos de solicitud o respuesta, y más.
- Plantillas: Express no impone una plantilla específica, pero es compatible con varias, como EJS, Pug (anteriormente conocido como Jade), y Handlebars. Esto facilita la renderización de vistas en el servidor.
- Gestión de sesiones y cookies: Express facilita la implementación de la gestión de sesiones y el manejo de cookies.
- Manejo de errores: Proporciona un sistema simple para manejar errores durante el procesamiento de las solicitudes.
- Middleware de terceros: Puedes aprovechar una gran cantidad de middleware de terceros que simplifican tareas comunes, como la autenticación con Passport.js, la compresión de respuestas con compression, y muchos otros.
Proyecto Express¶
Para comenzar a utilizar Express, primero debes instalarlo a través de npm (el sistema de gestión de paquetes de Node.js). Puedes hacerlo con el siguiente comando: npm install express
Una vez instalado, importamos el paquete express y creamos una variable para poder trabajar con los métodos y variables de express. Con el método express()
se crea una aplicación de express:
Para iniciar el servidor se usa el método listen()
, muy parecido al método nativo, que recibe el puerto que debe escuchar y una callback que ejecutará cuando se inicie el servicio:
const PORT = process.env.PORT ?? 1234
app.listen(PORT, () => {
console.log(`Server listening http://localhost:${PORT}`)
})
Express tiene diferentes métodos que nos permite trabajar con los métodos HTTP sin necesidad de tener que tratarlo en una estructura condicional. Existe un método de express para cada método HTTP, get()
, post()
, patch()
, put()
, delete()
, etc. Estos métodos reciben dos parámetros, en el primero la ruta que debe actuar, y en el segundo una callback que permite tratar con la request y el response:
Como se puede observar en el método anterior, express tiene métodos para poder trabajar con el response de manera sencilla:
status()
: Indica el estado del response, por defecto será 200.send()
: envía el response. Una de las ventajas de este método, es que identifica de forma sencilla el tipo de contenido a retornar, por lo que no sería necesario indicarle el header Content-Type.json()
: envía el response pero además con el Content-Type en formato JSON.
Tratamiento de las rutas¶
Como ya se vio en el tema anterior, una ruta puede estar definida de la siguiente manera: https://midominio.es/endpoint/param?queryName=queryValue
donde :
midominio.es
es el dominio de la web.endpoint
es el nombre del recurso con el que tratar.param
es el parámetro para obtener el recurso indicado, como por ejemplo una idqueryName=queryValue
es el par clave-valor, donde la clave es el nombre de la instancia a localizar y el valor es su valor. Puede haber tantas queries como sea necesario, separándolas con&
Por ejemplo, con la url https://midominio.es/users/60?deleted=false
, localizamos los usuarios cuya id sea 60, pero los que tengan el atributo deleted a false.
Para acceder tanto a los parámetros como a la query, debemos conocer muy bien la url. Sin embargo, express trabaja con un paquete llamado path-to-regexp
que permite indicar expresiones regulares a las rutas y acceder a ellas de forma más sencilla.
Una de las características de este paquete son los parámetros nombrados, donde se indicaría en la ruta el nombre del parámetro y se pueda acceder a él a través del objeto params
de la request:
Para poder trabajar con las queries, express tiene una propiedad llamada query
que almacena en un objeto todos los pares clave-valor:
Método use¶
Express tiene un método denominado use()
, dicho método se utiliza para indicar una operación para todo los tipos de métodos. Su uso mayoritario suele ser para trabajar con middlewares en la aplicación, pero cierto que es que se puede usar para cualquier otra cosa, siempre y cuando se tenga en cuenta que no importa el método que se realiza en la petición.
Por ejemplo, podemos usarlo para la ruta pokemon/all, que mostrará un mensaje de error, por que no es una ruta válida:
Incluso, se puede usar sin indicar ruta, por lo que se traducirá que cualquier ruta indicada en cualquier método hará una llamada al callback:
Hay que tener en cuenta, que el orden en el que se realizan los métodos HTTP, así como sus rutas son de total importancia. Cuando usábamos la forma nativa, se veía de forma más clara, por que usábamos varios cases y como default, se mostraba un mensaje de error con código 404. Sin embargo, con express se pierde la estructura condicional, pero su funcionamiento es bastante similar, va comprobando método a método si coincide con lo que ha entrado en la request y en caso de coincidir entra y realiza el response. Por ello, cuando queremos usar el método use
para indicar que una ruta no es correcta, es importante colocar dicha operación al final de las indicaciones de la ruta, de esta forma, validará todos los métodos y rutas y si no coincide con ninguna, entrará en el método use()
. Para ello, el orden recomendado sería:
- Acceso a los middleware
- Acceso a los recursos de forma directa, por ejemplo /users.
- Acceso a los recursos con parámetros, por ejemplo /users/50. Si se indicase este tipo de ruta antes que las rutas de recursos de forma directa /users, podrían entrar en estas antes (ya que la id, no es un parámetro obligatorio), y dar lugar a resultados no deseados.
- Acceso al método `use() como última opción, para devolver un 404.
app.get('/pokemon', (req, res) => {
//...
})
app.get('/pokemon/:id', (req, res) => {
// ...
})
app.post('/pokemon', (req, res) => {
//...
})
// ...
app.use((req, res) => {
// ...
})
También es recomendable agrupar todas las rutas por métodos, es decir, poner primero todas las rutas de un método, por ejemplo GET, y después de otro método, por ejemplo POST.