A fondo con NodeJS 0.12
Un artículo de Rafa G. Blanes
Me atrajo NodeJS desde un principio, cuando oí eso de código de servidor escrito en javascript. Después de aprender las nociones básicas hace un par de años, integrarlo con multitud de módulos y estar a punto de terminar un proyecto completo con este framework, en el que he estado trabajando en el último año, puedo decir que aún viendo sus pros pero también sus contras, sigue siendo para mí una maravillosa plataforma sobre la que construir aplicaciones escalables y mantenibles.
Framework, plataforma, tecnología... se mezclan un poco los conceptos: NodeJS te ofrece el core o framework esencial sobre el que construir aplicaciones, junto con un modelo de programación basado en eventos y una serie de módulos básicos pero muy importantes.
Lo que le da vida realmente a un proyecto con NodeJS es el enorme y vasto ecosistema de módulos que existe a su alrededor, que fueron apareciendo desde el primer momento en que NodeJS salió a escena y que hoy día siguen creciendo y evolucionando.
Esto es algo típico y la tendencia natural en software, como Drupal, Wordpress o el recién salido del horno ASP.NET 5 como framework de aplicaciiones web, sin cuya constelación de módulos que extienden o mejoran su funcionalidad no serían lo que son hoy en día.
Pero no es sólo cuestión de elegir e integrar un conjunto de módulos: es necesario utilizar un grupo de herramientas para una correcta gestión de la configuración de tu proyecto y para la puesta en marcha de los flujos de trabajo que hayas definido, además de aplicar continuamente buenos principios de desarrollo, clean code y una refactorización siempre presentes.
En este proyecto web con un backend bastante pesado en el que llevo trabajando un año he tenido oportunidad de usar NodeJS en profundidad, leyendo multitud de libros, muchos posts y artículos sobre buenas prácticas y buscando y analizando los módulos más populares o maduros para incorporar toda la funcionalidad.
A continuación cuento un poco mi experiencia que básicamente se basa en la pregunta recurrente de cómo hago esto y ahora cómo hago esto otro aún mejor y así hasta que el proyecto comienza a alcanzar cierta madurez, cuando todo el trabajo realizado comienza a converger en algo más palpable y empieza a verse un proyecto que ofrece cierta utilidad, o eso es al menos lo que esperas.
He utilizado una aproximación lean al proyecto, esto es, voy a cerrar un conjunto de funcionalidad muy bien definida y después es el mismo proyecto el que va a validar con los usuarios (los primeros son siempre tus amigos y familiares) si es de alguna utilidad..., si hay que seguir (;-), pivotar (;-| o comenzar otra cosa distinta (;-(.
Me fascina la aproximación lean, ya que en realidad construyes experimentos que después el mercado valida. Si no sabes qué es la aproximación lean de proyectos, comienza leyendo el libro clásido de Eric Ries.
En cuanto a los módulos que estoy usando, los agruparé funcionalmente.
En el core de la aplicación, puedo desglosar los siguientes módulos principales:
- Express como framework para lo esencial de una aplicación web. Prácticamente es lo estándar en el mundo NodeJS y posee una enorme constelación de middlewares para la gestión de sesiones (express-session), gestión de los parámetros de un request o post (body-parser), cookies (cookie-parser), enrutado (lo gestiona directamente express), seguridad (protección CSRF con csurf), etc. Aunque hay otras opciones más flexibles, he usado ejs como herramienta de plantillas. También he usado compression para el envío comprimido de los contenidos en cada request.
- Compresión de ficheros con archiver.
- Gestión de imágenes con fabric.js (sí, tiene un módulo que permite usar fabric en el lado del servidor) así como canvas.
- Obtención de valores únicos y hashs con node-uuid, hashids (para la generación elegante de enlaces cortos) y md5 (para crear valores hash a partir de cadenas de texto).
- Framework para logueo de usuarios con Passport; sus extensiones te permiten integrar fácilmente loguee con Facebook, Google+ o Twitter.
- Q como librería para usar promises y evitar el anidamiento de funciones asíncronas (callback hell) que impiden escribir un código legible.
- Cliente para usar Redis como servidor de objetos de caché y almacenamiento en ella de sesiones de usuario.
- Search-index como mecanismo sencillo y útil para indexar los contenidos del site y poder realizar búsquedas.
- Módulo cliente de Sendgrid para el envío de correos electrónicos usando ese mailer.
- cron para gestionar la ejecución de operaciones recurrentes de gestión y mantenimiento del site.
- winston como librería avanzada para mensajes de log.
- Para escribir código más legible y mantenible, he usado profusamente lodash (esto es una oblicación para cualquier desarrollador que use javascript, aunque hay otras opciones similares).
- html-minifier para la minificación de contenidos al ser enviados en cada request.
No es que haya elegido todos esos módulos al azar, sino después de un proceso y trabajo de prueba, evaluación y experimentación, así como leyendo muchos blogs y viendo lo que la comunidad usa con más frecuencia.
¿Y qué hay de las pruebas? Ningún proyecto software puede considerarse maduro y profesional si no está respaldado por pruebas.
Para ello he usado, cómo no, chai como librería de asersiones y mocha para la ejecución de las pruebas. El resultado y la experiencia con ambas librerías ha sido y es magnífico.
El site gestiona multitud de ficheros de diverso tipo (no, no es una página más de enlaces y descargas...), de modo que después de evaluar diversas opciones cloud como CDNs me decanté com Amazon AWS y su paquete aws-sdk para la integración de su API REST en NodeJS.
Del mismo modo, el site se apoya en una base de datos MySql, para lo que he usado el cliente mysql para su integración con la aplicación.
El desarrollo de una aplicación no consiste sólo en hacer que esta funcione, más o menos respaldada por pruebas: también hay que definir flujos de trabajo para generar los assets del proyecto que finalmente serán desplegados en producción.
Para ello he usado, cómo no, grunt y muchos módulos básicos para generar la aplicación para su despliegue. Aunque su mismo nombre indica su propósito, a continuación indico los más relevantes: