Node Js
Node Js
JS
Cuando se trata de desarrollar un sitio web lo primero que tenes que considerar es cómo lo querés
construir, como un sitio web estático o como un sitio web dinámico. Pero, ¿qué hace que un sitio web
sea categorizado “estático” o “dinámico”?
Te invito que me acompañes en este comparativo para que conozcas cómo distinguir las diferencias
entre estos dos tipos de páginas web y que puedas decidir cuál es el que te conviene según tu necesidad.
Pero antes de entrar en detalles de cada uno de estos tipos de sitios web, primero debes entender cómo
funciona la comunicación en Internet cuando queremos ver una página web.
• El costo inicial de una página web estática puede ser mucho menor que al de una
dinámica.
Por su naturaleza estática, la complejidad y tiempo de desarrollo es menor porque no requiere del uso
de lenguajes de programación o bases de datos, y por ende su costo monetario es más bajo.
Dado a su naturaleza independiente, cada página puede tener un diseño diferente. No es necesario un
solo diseño para múltiples tipos de contenido, lo que en los sitios web dinámicos se le conoce como
plantillas (templates).
Ya que los sitios web estáticos son construidos previamente. No implica ejecución de scripts o
secuencias de comandos complejas, bases de datos ni análisis de contenido a través de lenguajes de
plantillas, etc.
Sin embargo, con la revolución del Jamstack, los generadores de sitios web estáticos como Jekyll,
GatsbyJS o Eleventy, y los Headless CMS como Netlify CMS, Siteleaf o Forestry, y además la
incorporación de CDN (Content Delivery Network en inglés) para gestionar los recursos multimedia,
se puede generar un aumento en el tiempo de carga de una página web estática dependiendo de sus
características.
Para usuarios no técnicos, una vez que la página es creada, hacer pequeños ajustes en el contenido
puede representar un desafío a menos que estén familiarizados con HTML, CSS y el código del sitio
web en general. Si no es así, es posible que deban pedirle al desarrollador que la creó originalmente,
que realice los cambios que necesitan.
Esto puede verse como una consecuencia de la desventaja anterior. Es decir que, con el tiempo, el
mantenimiento de un sitio estático puede generar costos de mantenimiento continuo que podrían
evitarse si tuvieras una página web dinámica.
• Agregar nuevas páginas o funcionalidades a una web estática puede ser más difícil que
hacerlo para una web dinámica.
Por ejemplo, si creas una página web para promocionar productos de tecnología, cada vez que querés
agregar un producto, como un nuevo televisor o un nuevo celular, tendrías que crear una nueva página
específicamente para ese producto, lo que puede llevar mucho tiempo además del costo que puede
llevar este proceso.
Esto permite que el usuario pueda solicitar información fácilmente de una manera organizada y
estructurada dentro de un catálogo, además de crear y mostrar contenido según el tipo de usuario que
acceda a la página.
Al coste del desarrollo de la página web se le suma el coste del desarrollo de las bases de datos donde
se guardará el contenido a mostrar, etc. El desarrollo también puede costar más a medida que se
agregan nuevas funcionalidades. Si bien los costos de mantenimiento pueden ser más bajos como fue
mencionado en las ventajas, también puede involucrar costos de desarrollo iniciales mucho más altos
que al desarrollar una página web estática.
Aquí, cada vez que se recarga la página, se mostrará la fecha y hora actual, es decir será diferente en
cada recarga de la página, ya que la instrucción <%=Datetime.Now()%> le indica al servidor que
retorne la fecha del momento en que recibe la petición.
Antes de indagar en Node.js, tenés que leer acerca de los beneficios de utilizar
JavaScript a través del stack, que unifica el idioma y el formato de datos (JSON), lo
que permite reutilizar de manera óptima los recursos del desarrollador. Como esto es
más un beneficio de JavaScript que de Node.js específicamente, no hablaremos
mucho de ello aquí. Sin embargo, es una ventaja clave para la incorporación de Node
en su pila.
La web de Node indica: “Node.js es un entorno en tiempo de ejecución
multiplataforma, de código abierto, para la capa del servidor (pero no limitándose a
ello) basado en el lenguaje de programación ECMAScript, asíncrono, con I/O de
datos en una arquitectura orientada a eventos y basado en el motor V8 de Google.”
Más allá de eso, vale la pena señalar que el creador de Node.js, Ryan Dahl fue
encargado a crear sitios web en tiempo real con función de inserción, “inspirado por
aplicaciones como Gmail”. En Node.js, dió a los desarrolladores una herramienta
para trabajar en el paradigma no-bloqueante, event-driven I/O.
Con todas sus ventajas, Node.js ahora juega un papel crítico en la pila de tecnología
de muchas empresas de alto perfil que dependen de sus exclusivas ventajas.
Vamos a analizar no sólo cómo estas ventajas son obtenidas, sino también por qué es
posible que desees utilizar Node.js y por qué no usar algunos de los clásicos modelos
de aplicaciones web como ejemplos.
¿Cómo funciona?
Una lista completa de los paquetes de módulos puede encontrarse en el sitio web de
NPM Https://npmjs.org/ o acceder utilizando la herramienta de la CLI de NPM que
automáticamente se instala con Node.js. El módulo es un ecosistema abierto a todos,
y cualquiera puede publicar su propio módulo que será incluido en el repositorio de
NPM. Una breve introducción a la NPM (un poco viejo, pero sigue siendo válido) se
puede encontrar en http://howtonode.org/introduction-to-npm.
Algunos de los más populares hoy en día son módulos de NPM:
Es la forma más típica en tiempo real y una multi-aplicación de usuario. Desde IRC ,
a través de muchos propietarios y protocolos abiertos girando en puertos no estándar,
con la capacidad de instrumentar todo en Node.js con websockets corriendo sobre el
puerto estándar 80.
En el lado del servidor, tenemos un simple Express.js que implementa dos cosas: 1)
Obtener un controlador de solicitudes ‘/’ que sirve la página web que contiene un
tablero de mensajes y un botón ‘Enviar’ para inicializar el nuevo mensaje de entrada,
y 2) un servidor websockets que escucha los mensajes emitidos por los clientes de
websocket.
En el cliente, tenemos una página HTML con un par de controladores, uno para el
Send’ evento de clic de botón, que recoge el mensaje de entrada y lo envía hacia
abajo el websocket, y otro que escucha los mensajes entrantes del nuevo cliente de
websockets (es decir, los mensajes enviados por otros usuarios, que el servidor ahora
quiere que el cliente muestre).
1. El explorador atrapa el clic con el botón ‘Send’ a través de un controlador de JavaScript que
recoge el valor del campo de entrada (es decir, el texto del mensaje), y emite un mensaje al
websocket utilizando el cliente conectado a nuestro servidor (inicializado con la página web).
Por ejemplo, si estás utilizando Rails, tendrías que convertir los datos de JSON para
modelos binarios y después exponer nuevamente como JSON sobre HTTP cuando el
dato es consumido por el backbone.js, angulares, etc., o incluso llamadas AJAX
jQuery normal. Con Node.js, simplemente podés exponer tus objetos JSON con una
API REST para que el cliente consuma. Además, no necesitas preocuparte por la
conversión entre JSON y cualquier otra cosa al leer o escribir desde su base de datos
(si estás usando MongoDB). En conclusión, podés evitar la necesidad de realizar
varias conversiones mediante un formato de la serialización de datos uniformes a
través del cliente, servidor y base de datos.
Entradas en espera
Si estás recibiendo una gran cantidad de datos concurrentes, tu base de datos puede
ahogarse. Como se ha descrito más arriba, Node.js puede manejar fácilmente las
conexiones simultáneas al mismo tiempo. Pero debido a que el acceso a la base de
datos es una operación de bloqueo (en este caso), nos topamos con problemas. La
solución es reconocer el comportamiento del cliente antes de que los datos se
escriban en la verdadera base de datos.
Con ese enfoque, el sistema mantiene su sensibilidad bajo una carga pesada, lo que es
particularmente útil cuando el cliente no necesita una firme confirmación de la
correcta escritura de datos. Ejemplos típicos incluyen: el registro o la escritura de
datos de seguimiento de usuario, procesamiento en lotes que no se utilizan hasta un
momento posterior, así como las operaciones que no necesitan ser reflejadas al
instante (como actualizar el recuento de Likes en Facebook) donde la coherencia final
(tan a menudo utilizadas en el mundo NoSQL) es aceptable.
Los datos se ponen en cola a través de algún tipo de caché o de Message Queue
Server (por ejemplo, infraestructura, RabbitMQ, ZeroMQ) y resumido por un proceso
separado escrito en lote, cálculo o procesamiento intensivo servicios backend, escrito
en un mejor desempeño de plataforma para tales tareas. Un comportamiento similar
puede implementarse con otros lenguajes/frameworks, pero no con el mismo
hardware o con el mismo alto, para mantener su rendimiento.
En resumen: con Node, podés empujar la base de datos escrita a un lado y tratar con
ella más tarde, para proceder como que si esta hubiera sido exitosa.
Transmisión de Datos
En plataformas web más tradicional, las peticiones y respuestas HTTP son tratadas
como eventos aislados; de hecho, son realmente corrientes. Esta observación puede
ser utilizada en Node.js para construir algunas características interesantes. Por
ejemplo, es posible procesar archivos mientras están siendo cargados, ya que los
datos entran a través de un arroyo, y pueden ser procesados en una línea de moda.
Esto podría hacerse en tiempo real para la codificación de audio o vídeo, como proxy
entre diferentes fuentes de datos (véase la sección siguiente).
PROXY
Node PROXY.js es empleado como un servidor proxy el cual puede manejar una gran
cantidad de conexiones simultáneas en un modo de no-bloqueo. Es especialmente útil
para proxy de diferentes servicios con distintos tiempos de respuesta, o para la
recopilación de datos desde varios puntos de origen.
Aunque existen servidores de proxy dedicados, utilizando en su lugar Node podría ser
útil si su infraestructura de servidores proxy es inexistente o si necesita una solución
para el desarrollo local. Con esto, quiero decir que se podría construir una aplicación
del lado del cliente con un servidor de desarrollo Node.js para activos como
proxy/stubbing solicitudes de API, mientras que en la producción manejarías tales
interacciones con un dedicado servicio de proxy (nginx, HAProxy, etc.).
Brokerage-Dashboard del Stock Trader
Cambiar a tiempo real es una solución basada en la web que permitiría a los
corredores cambiar fácilmente de estaciones de trabajo o lugares de trabajo. Pronto
podríamos comenzar a verlos en la playa de Florida, Ibiza…o Bali.
Imagina cómo podría mejorar tu negocio si supieras lo que estuvieran haciendo tus
visitantes en tiempo real; si pudieras visualizar sus interacciones. Con el tiempo real,
ahora podés tomar dos vías de Node.js.
Tanto internos (intra-empresa) como también los de los servicios públicos de los
Estados, pueden ser reportados en vivo y a tiempo real utilizando esta tecnología.
Empuja esta idea un poco más lejos y trata de imaginar un centro de operaciones de
red (NOC) en aplicaciones de supervisión de un operador de telecomunicaciones,
cloud/red/proveedor de servicios de hosting, o alguna institución financiera, todos se
ejecutan en el open web stack respaldado por Node.js y Websockets en lugar de Java
y/o applets de Java.
Nota: No intentes construir sistemas a tiempo real duros en Node (es decir, sistemas
que requieran tiempos de respuesta coherentes). Erlang es probablemente una mejor
elección para esta clase de aplicación.
Node.js con Express.js también pueden ser utilizados para crear aplicaciones web
clásicas en el servidor. Sin embargo, mientras sea posible, este paradigma en
petición-respuesta de Node.js sería llevar alrededor de HTML, no es el más típico de
los casos de uso. Hay argumentos para estar a favor y en contra de este enfoque. Aquí
están algunos hechos a considerar:
PROS:
Si tu aplicación no tiene ningún cálculo intensivo del CPU, podés construir en Javascript de
arriba a abajo, inclusive a nivel de base de datos si utilizas el objeto de almacenamiento JSON como
MongoDB DB. Esto facilita el desarrollo (incluyendo la contratación) significativamente.
Los Crawlers reciben una respuesta totalmente HTML, que es mucho más SEO-friendly,
digamos, una sola página o en una aplicación de Websockets app se ejecuta sobre Node.js.
CONS:
Un CPU de cálculo intensivo bloqueará la receptividad del Node.js, por lo que una
plataforma de roscado es un mejor enfoque. Alternativamente, podrías intentar escalar el cómputo
[*].
Utilizando Node.js con una base de datos relacional es aún bastante doloroso (leer más abajo
para ver más detalles). Hazte un favor y escoge cualquier otro entorno como Rails, Django, o
ASP.NET MVC si estás intentando realizar operaciones relacionales.
Comparando Node.js con Express.js en contra de Ruby on Rails, por ejemplo, hay una
decisión clara en favor de esta última cuando se trata de acceso a datos relacionales. El
DB relacional con herramientas para Node.js está aún en sus primeras etapas; es
bastante prematuro y por ende no tan agradable trabajar con ello. Por otro lado, Rails
automáticamente proporciona datos de configuración del acceso a la derecha de la caja
junto con el esquema de base de datos y herramientas de soporte de migraciones de
otras Gemas (con doble sentido). Rails y su homólogo marco han madurado y probado
que Active Record Data Mapper recopila implementaciones del acceso a datos y que
echarás de menos si intentas replicarlo con JavaScript puro.[*]
Aún, si estás muy inclinado a permanecer en JS todo el camino, mantén un ojo sobre
Sequelize ORM y Nodo2 ya que ambos son todavía inmaduros, pero eventualmente
pueden alcanzar a los demás lenguajes de programación.
Cuando se trata de cómputo pesado, Node.js no es la mejor plataforma.
Definitivamente no querés construir un servidor de cálculo Fibonacci en Node.js. En
general, cualquier operación de uso intensivo de CPU anula todas las ventajas de
rendimiento y bloquearía cualquier petición entrante de un subproceso.
Por supuesto utilizarías el mismo enfoque en otras plataformas también, pero con
Node.js podés conseguir un alto reqs/s del que hemos hablado, ya que cada petición
es una tarea pequeña y un manejo muy rápido y eficientemente.
Conclusión
Hemos hablado de Node.js desde una teoría práctica, comenzando con sus objetivos y
ambiciones, y terminando con algunos de los escollos que tiene programar en ese
entorno. Cuando las personas tienen problemas con Node, casi siempre deducen al
hecho de que el bloqueo de operaciones son la raíz de todo mal. El 99% del abuso de
procesos en Node viene como consecuencia directa.
Para recordar: Node.js nunca fue creado para resolver el problema de escalado de
computación. Fue creado para resolver el problema de escalado de E/S, lo que lo hace
muy bien.
¿Por qué usar Node.js? Si el caso de uso no contiene operaciones intensivas del CPU
ni el acceso a los recursos de bloqueo, podés aprovechar los beneficios de Node.js y
disfrutar de aplicaciones de red rápidas y escalables. Bienvenido a la web en tiempo
real.
¿Porque usar Node.Js?
Inicialmente uno de los puntos que se deben tener en claro es que Node.JS por definición es
un entorno de ejecución para JavaScript. Así mismo, sus características son aquellas que hacen
que sea tan interesante a la hora de utilizarlo ya bien sea para un desarrollo batch, un servicio web,
una API Rest o cualquier herramienta a nivel de batch.
Anteriormente, los desarrolladores de JavaScript sólo podían utilizar este lenguaje con la obligación
de utilizar un navegador web ya sea Firefox, Chrome, entre otros. Lo que ocasionaba que se tuviera
una limitación a la hora de realizar cierto tipo de aplicaciones, ya que no se podían generar o
programar aplicaciones que se renderizaran en el servidor.
Con la llegada de Node.JS, se abrió un nuevo mundo y empezaron a surgir los servidores web hechos
con Express o con otras librerías basadas en Node, las de API Rest, incluso se abrió un nuevo mundo
a la hora de desarrollar para IOT. Por ejemplo: las placas arduino, ya que éstas se pueden desarrollar
con Node en una aplicación y utilizarlas en ese tipo de placas. Con lo cual, se puede decir que Node
tiene una cantidad considerable de características entre las cuales destacan las siguientes:
• Operaciones de E/S sin bloqueos: Node está pensado para que las operaciones de
entrada y salida sean sin bloqueos, por ejemplo: un servidor web realiza una petición única y
espera una respuesta.
Node.JS es una buena opción para desarrollar cierto tipo de cosas como lo son:
• Servidores Web: Con el uso de librerías que se encuentran en los paquetes propios de
Node.JS o de terceros como Express, Koa y Hapi.
• Sockets: Son eventos que para realizar chats y aplicaciones en tiempo real es una
excelente opción, sobretodo gracias a su gran velocidad.
• IOT: Programar placas pequeñas con poco hardware como un Arduino, permite
desarrollar una aplicación y desplegarla.
Instalación de NodeJS en Windows
$ node
console.log("hola mundo");
Comparación de código
Los métodos de bloqueo se ejecutan de forma sincrónica y los métodos sin
bloqueo se ejecutan de forma asincrónica .
Usando el módulo Sistema de archivos como ejemplo, este es
un archivo síncrono leído:
const fs = require('fs');
const data = fs.readFileSync('/file.md'); // blocks here until file is read
El primer ejemplo parece más simple que el segundo, pero tiene la desventaja de
que la segunda línea bloquea la ejecución de cualquier JavaScript adicional hasta
que se lea todo el archivo. Tenga en cuenta que en la versión síncrona, si se
produce un error, será necesario detectarlo o el proceso se bloqueará. En la
versión asincrónica, depende del autor decidir si se debe producir un error como
se muestra.
Ampliemos un poco nuestro ejemplo:
const fs = require('fs');
const data = fs.readFileSync('/file.md'); // blocks here until file is read
console.log(data);
moreWork(); // will run after console.log
Simultaneidad y rendimiento
La ejecución de JavaScript en Node.js es de un solo subproceso, por lo que la
concurrencia se refiere a la capacidad del bucle de eventos para ejecutar
funciones de devolución de llamada de JavaScript después de completar otro
trabajo. Cualquier código que se espere que se ejecute de manera concurrente
debe permitir que el bucle de eventos continúe ejecutándose mientras se están
produciendo operaciones que no son de JavaScript, como E / S.
Como ejemplo, consideremos un caso en el que cada solicitud a un servidor web
tarda 50 ms en completarse y 45 ms de esos 50 ms son E / S de base de datos que
se pueden realizar de forma asincrónica. La elección de operaciones
asincrónicas sin bloqueo libera esos 45 ms por solicitud para manejar otras
solicitudes. Esta es una diferencia significativa en la capacidad con solo elegir
usar métodos sin bloqueo en lugar de métodos de bloqueo .
El bucle de eventos es diferente a los modelos en muchos otros lenguajes donde
se pueden crear hilos adicionales para manejar el trabajo concurrente.
Peligros de mezclar código de bloqueo y no bloqueo
Hay algunos patrones que deben evitarse cuando se trabaja con E / S.
Veamos un ejemplo:
const fs = require('fs');
fs.readFile('/file.md', (err, data) => {
if (err) throw err;
console.log(data);
});
fs.unlinkSync('/file.md');
El código mostrado abajo, muestra como puede importarse un modulo con base a su nombre, como
ejemplo se utiliza el framework Express . Primero se invoca la función require(), indicando como
parámetro el nombre del módulo o librería como una cadena ('express'), posteriormente se invoca
el objeto obtenido para crear una aplicación Express.