A menos que hayas vivido bajo una piedra en los últimos años, sabrás que JavaScript está rompiendo todos los esquemas de desarrollo. De hecho, pasó de ser simplemente una herramienta que ayudaba a crear sitios responsivos en front end (del lado del cliente), a contar con una innumerable serie de frameworks que permiten su uso inclusive en back end (del lado del servidor).

¿Cómo es que esto funciona? y lo mas importante… ¿Funciona? En el siguiente artículo trataré de responder tus preguntas en torno a Node. Te presentaré una serie de problemas que Node resuelve, cómo ejecutar una aplicación simple y en dónde Node es una solución viable. Acompáñame.

¿Qué problemas resuelve Node.js?

Node, en su página web, declara su meta: “Node está diseñado para construir aplicaciones en red escalables”, puede parecer una meta un tanto presuntuosa… o no? Pensemos en los programas de servidor actuales y tomemos como referencia a los tres pesos pesados de este entorno: JAVA, php y .NET, cada conexión genera un nuevo hilo que potencialmente viene acompañado de 2MB de memoria. En un sistema de 8 GB de RAM por ejemplo, esto da un máximo (teórico) de 4000 conexiones concurrentes, es decir, apenas 4000 usuarios se podrán conectar a este sistema. A medida que la base de clientes se expande, el dueño del sitio tendrá que invertir en más y más recursos que podrían en algún punto comprometer sus ganancias. (Sin contar que con más recursos se añaden más nodos y el número de accidentes potenciales se incrementa). Esto nos lleva a la premisa que todos conocemos: “El cuello de botella de una arquitectura web es el número máximo de conexiones concurrentes que puede manejar un servidor”.

Node resuelve este problema cambiando la forma en la que se conecta el cliente con el servidor. En lugar de generar un nuevo hilo con el OS para la conexión (y de asignarle una cantidad de memoria), cada ejecución dispara una ejecución de evento dentro del proceso del motor de Node.

Ahora que tenemos un programa que puede manejar miles de conexiones concurrentes… ¿Qué se puede construir con Node? La respuesta al final de este artículo.

Lo que Node no es…

Si… Node es un programa de servidor, diseñado para estar ahí cuando se lo necesite, pero a diferencia de Apache o Tomcat, Node no es un programa al cual se deba dar doble click para que funcione. La diferencia radica en que Node tiene el concepto de Módulos. Hay cientos de módulos de los que se puede escoger con Node y la comunidad es bastante activa en cuanto a producir, publicar y actualizar docenas de módulos por día. Hablaremos sobre toda la parte de módulos de Node en un futuro artículo ya que es un tem bastante extenso.

 

¿Cómo funciona Node?

Node ejecuta V8 JavaScript. Espera… ¿qué? ¿JavaScript en el servidor? Sí… lo leíste correctamente. El JavaScript del lado del servidor puede ser un concepto nuevo para cualquiera que haya trabajado exclusivamente con JavaScript del lado del cliente, pero la idea en sí no es tan inverosímil… ¿Por qué no utilizar el mismo lenguaje de programación que se usa en el cliente del lado del servidor?

¿Qué es el V8?

El motor V8 JavaScript es el motor JavaScript subyacente que Google usa con su navegador Chrome. Pocas personas piensan en lo que en realidad sucede con JavaScript en el cliente. Bien, un motor JavaScript en realidad interpreta el código y lo ejecuta. Con el V8, Google creó un intérprete ultra-rápido escrito en C++, con otro aspecto único: se puede descargar el motor e incorporarlo a cualquier aplicación que desee. No está restringido a ejecutarse en un navegador. Así, Node en realidad usa el motor V8 JavaScript escrito por Google y le da otro propósito para usarlo en el servidor. ¡Perfecto! Para qué crear un nuevo lenguaje cuando ya hay una buena solución disponible.

 

Programación orientada por eventos

A muchos programadores se les ha hecho creer que la programación orientada a objetos es el diseño perfecto de programación y que no deben usar nada más. Node utiliza lo que se conoce como modelo de programación orientado por eventos.

Recordemos a JQuery y su manejo de eventos:

$("#mi_boton").click(function(){
if ($("#mi_campo_de_texto").val() != $(this).val())
alert("¡¡¡¡Los valores en el campo de texto y el texto del botón no coinciden!!!!");
});

¿Qué acabamos de hacer? Nada más simple, le asignamos un evento tipo click al botón con id="mi_boton" y pusimos la condición de que el campo de texto id="mi_campo_de_texto" deba ser igual al texto de mi_boton. Tan fácil como eso.

El lado del servidor realmente no es tan diferente del lado del cliente. Es verdad, no se están presionando botones, y no se está ingresando texto en campos, pero a un nivel superior, están sucediendo eventos:

Se realiza una conexión — ¡evento!

Se reciben datos a través de la conexión — ¡evento!

Se dejan de recibir datos por la conexión — ¡evento!

¿Por qué este tipo de configuración es ideal para Node? JavaScript es un gran lenguaje para programación orientada por eventos, porque permite funciones y cierres anónimos, y más importante, la sintaxis es similar para casi cualquier persona que haya codificado. las funciones de devolución de llamado que se llaman cuando ocurre un evento pueden escribirse en el mismo punto en el que se captura el evento. Fácil de codificar, fácil de mantener. No hay infraestructuras complicadas Orientadas a Objeto, no hay interfaces, no hay potencial para sobre-arquitectura de nada. Simplemente esperar por un evento, escribir una función de devolución de llamado, ¡y listo!

Node, ¿para qué sirve?

Entonces, después de leer todo sobre Node, tal vez ya puedas responder la pregunta “¿Qué es Node?” pero puede que te quedes con la duda sobre “¿En qué puedo utilizar Node?” Esa es una pregunta importante ya que hay algunas cosas para las que Node es realmente bueno.

Como has visto hasta ahora, Node está extremadamente bien diseñado para situaciones en que se esté esperando una gran cantidad de tráfico y donde la lógica del lado del servidor y el procesamiento requeridos, no sean necesariamente grandes antes de responder al cliente. Aquí hay algunos buenos ejemplos en donde Node haría un gran trabajo:

  • Una API RESTfulUn servicio Web que proporcione una API RESTful toma algunos parámetros, los interpreta, arma una respuesta y descarga esa respuesta (usualmente una cantidad relativamente pequeña de texto) de vuelta al usuario. Esta es una situación ideal para Node, porque puede construirse para que maneje decenas de miles de conexiones. Tampoco requiere una gran cantidad de lógica y básicamente sólo busca valores de una base de datos y los reúne como una respuesta. Como la respuesta es una pequeña cantidad de texto y la solicitud entrante es una pequeña cantidad de texto, el volumen de tráfico no es alto, y una máquina probablemente puede manejar las demandas de API de incluso la API de la más ocupada de las empresas.
  • Fila de TwitterPensemos en una compañía como Twitter que recibe tweets y los escribe en una base de datos. Literalmente hay miles de tweets llegando cada segundo y la base de datos posiblemente no puede seguir el ritmo del número de escrituras necesarias durante los horarios pico de uso. Node se convierte en una pieza clave de la solución a este problema. Como hemos visto, Node puede manejar decenas de miles de tweets entrantes. Luego puede escribirlos rápida/fácilmente en un mecanismo de cola en memoria (memcached, por ejemplo), desde donde otro proceso separado puede escribirlos en la base de datos. El rol de Node en esto es reunir rápidamente el tweet y pasar esta información hacia otro proceso responsable de escribirlo. Imaginemos otro diseño,  un servidor PHP normal por ejemplo,  que intente manejar escrituras en la base de datos misma. Cada tweet podría causar una pequeña demora mientras se escribe en la base de datos, dado que el llamado de base de datos estaría bloqueando. Una máquina con este diseño sólo podría manejar 2.000 tweets entrantes por segundo, debido a la latencia de base de datos. A un millón de tweets por segundo, usted estaría hablando de 500 servidores. Node, en cambio, maneja cada conexión y no causa bloqueo, permitiéndole capturar tantos tweets como se le puedan arrojar. Una máquina nodo capaz de manejar 50.000 tweets por segundo, y usted estaría hablando de sólo 20 servidores.
  • Estadísticas de videojuegosSi alguna vez alguna vez jugaste un juego como Dota 2 on-line, algunas cosas te habrán llamado la atención inmediatamente cuando observaste las estadísticas del juego, principalmente el hecho de que deben estar rastreando toneladas de información sobre el juego para poder producir tal nivel de estadísticas. Luego, multiplica esto por los millones de personas que lo juegan en cualquier momento, y tendrás una idea de la inmensa cantidad de información que se genera con bastante rapidez. Node es una buena solución para este escenario, porque puede capturar los datos que están generando los juegos, hacer un mínimo de consolidación con ellos y luego ponerlos en una fila para escribirlos en una base de datos. Parecería algo tonto dedicar todo un servidor a rastrear cuántas veces se planta un ward por ejemplo, lo cual podría ser el límite útil si se utilizara un servidor como Apache, pero parecería menos tonto si en lugar de ello se pudiera dedicar un solo servidor a rastrear casi todas las estadísticas de un juego, como se puede llegar a hacerlo con un servidor que ejecute Node.

Ejemplo de uso

La teoría es excelente pero…. siempre es bueno terminar con una pequeña porción de código.

Para replicar este tutorial en tu casa, deberás seguir una serie de pasos detallados en la web en español de Node, los he resumido para que no tengas que seguir odiosas documentaciones:

El clásico “Getting Started”

  1. Descarga el instalador de la página oficial de Node
  2. Abre un explorador de archivos de tu preferencia y crea una carpeta llamada: “Hola Mundo Node”
  3. Con un editor de texto de tu preferencia (recomiendo Visual Studio Code), crea un archivo llamado server.js

Hola mundo en Node.js

Para empezar node.js nos ofrece muchos módulos para utilizar, para el ejemplo vamos a escoger uno de ellos, este módulo se llama http.

El módulo http es el que nos va a permitir crear un servidor que pueda recibir peticiones HTTP, para esto necesitamos primero crear un servidor.

Para ello vamos a editar nuestro archivo llamado server.js

Para poder utilizar el módulo http primero debemos requerir este módulo. ¿Cómo requerimos módulos en Node.js? A continuación te lo muestro.

// server.js 'use strict'; 
const http = require('http');

El ‘use strict’ es una directiva de Javascript que describe que vamos a utilizar el modo estricto, esto es algo que deberían tener todos nuestros archivos de Node.js para hacer buen código Javascript.

Para requerir algún módulo debemos utilizar la palabra “require” con el nombre del módulo, esto lo guardamos en alguna variable en este caso la variable se llama “http”.

Una vez que ya tenemos este modulo solo nos faltaría crear el servidor y enviar el Hola Mundo.

const server = http.createServer(function (req, res) {
    res.writeHead(200, {'content-type': 'text/plain'});
    res.end('Hola Mundo');
}); server.listen(8000);

Para crear el servidor solo utilizamos el método createServer que nos lo da el modulo http, la función dentro de este método tiene 2 parámetros la petición y la respuesta (req, res). Después de eso lo que hace todo el trabajo es el res.end(), con eso enviamos algo al navegador como respuesta, res.writeHead() se encarga de escribir en la cabecera de la petición el código de estado 200 (pagina satisfactoria) y el tipo de contenido ‘text\plain’ (texto plano). La ultima linea le dice al servidor en que puerto va a escuchar, este puerto puede variar para el ejemplo le puse el 8000.

Con todo esto ya listo, el archivo server.js quedaría de esta manera.

// server.js 'use strict'; const http = require('http'); const server = http.createServer(function (req, res) {
    res.writeHead(200, {'content-type': 'text/plain'});
    res.end('Hola Mundo');
}); server.listen(8000);

Ahora solo debemos ejecutar este archivo, para eso vamos a la terminal, nos ubicamos donde se encuentra nuestro archivo server.js y lo ejecutamos.

$ node server.js

Luego vamos a nuestro navegador favorito, ingresamos a localhost:8000 y podremos ver el “Hola Mundo”

Espero que te haya gustado mi pequeño artículo sobre Node.js, una tecnología que ya está aquí y que en cuestión de tiempo se tomará a la mayor parte de aplicaciones web presentes en nuestro entorno.

Espero que sigas leyendo más de mi blog.

console.log('node.js');