Anuncios

Bienvenidos sean a este post, hoy veremos como trabajar con la segunda forma de manejar codigo intensivo.

Anuncios
Anuncios

En este post mencionamos que al momento de computar un codigo intensivo podemos tener serios problemas de performance pero para solucionarlo mencionamos dos formas: una era mediante el refactoreo y en este caso lo hicimos mediante funciones asincronicas y la otra era haciendo que el trabajo se realice mediante un servidor backend y el resultado se vea en un servidor frontend; hoy nos centraremos en ver esta segunda forma.

Anuncios

Basicamente para trabajar con esta forma vamos a realizar una solicitud GET a un servidor backend, la cual responde al numero fibonacci representado por la URL, por lo tanto refactorearemos a la aplicacion para hacer un servidor que llamaremos desde la aplicacion, si bien esto puede ser poco practico dado el tiempo de tarea pero nos servira para poder muy basicamente una aplicacion multi proposito.

Anuncios
Anuncios

Este tipo de servicio no deja de ser una operacion asincronica, lo cual implica que debemos tener una funcion encargada de iniciar una solicitud y otra para recibir la respuesta y dado que el servicio REST son accedidos mediante HTTP por lo que usaremos un objeto HTTPClient para esto, primero crearemos a nuestro servidor pero para ello necesitaremos el codigo de nuestra aplicacion sino lo poseen les dejo un link para descargarlo:

Anuncios

Una vez descargado extraigan el contenido en un directorio y nuestra aplicacion esta lista para ser usada, continuemos con este post, y para ello crearemos en el raiz de nuestra aplicacion un nuevo archivo con el nombre de servidorfibo.js y le agregaremos el siguiente codigo:

servidorfibo.js

const math = require('./math');
const express = require('express');
const logger = require('morgan');
const app = express();

app.use(logger('dev'));
app.get('/fibonacci/:n', (req, res, next) => {
        math.fiboasync(Math.floor(req.params.n), (err,val) => {
                if (err) next(`ERROR SERVIDOR FIBO ${err}`);
                else {
                        res.send({
                                n: req.params.n,
                                result: val
                        });
                }
        });
});

app.listen(process.env.SERVERPORT);
Anuncios
Anuncios

Primero importaremos las librerias que usaremos, en este caso primero la nuestra encargada de calcular el valor fibonacci, despues la de Express, luego la de morgan encargada del registro o log, y por ultimo crearemos un objeto de Express para poder acceder a sus metodos, lo primero que haremos sera llevar un log de lo realizado mediante logger y despues usaremos a get para obtener el resultado, observen que usamos la palabra fibonacci seguida de :n, esta es una particularidad de Express que nos permite recibir cualquier valor para poder procesarlo, despues tenemos los tres argumentos que hemos estado utilizando en posts anteriores donde se encargan de la solicitud, respuesta y pasar al siguiente ciclo, respectivamente, despues utilizaremos a la funcion fibonacci asincronica, de la cual hablamos en este post, pero aqui le pasaremos el valor de la url mediante req.params.n y despues tendremos un condicional donde en caso de error lo devolveremos, de lo contrario devolveremos el valor pasado en la URL y luego el resultado final, por ultimo le diremos que active el servidor en el puerto que le pasemos mediante SERVERPORT, con esto tenemos el script de nuestro servidor, nuestro siguiente paso sera ir al archivo package.json y en la seccion scripts la modificaremos de la siguiente manera:

  "scripts": {
    "start": "DEBUG=fibonacci:* node ./bin/www",
    "server": "SERVERPORT=3002 node ./servidorfibo.js"
  },
Anuncios

En este caso agregamos una nueva linea identificada como server y en la informacion primero pasaremos el valor de SERVERPORT, el de la ultima linea del codigo anterior, y luego ejecutaremos el archivo anterior mediante node, con esto realizado lo unico que debemos hacer es usar a npm run server para que funcione de la siguiente forma:

$ npm run server

> fibonacci@0.0.0 server
> SERVERPORT=3002 node ./servidorfibo.js
Anuncios

Ahora solo debemos abir otra ventana de terminal y usaremos a curl para conectarrnos al servidor, veamos un par de ejemplos:

$ curl -f http://localhost:3002/fibonacci/10
{"n":"10","result":55}
$ curl -f http://localhost:3002/fibonacci/20
{"n":"20","result":6765}
$ curl -f http://localhost:3002/fibonacci/30
{"n":"30","result":832040}
$
Anuncios

Mientras tanto del lado del servidor tendremos una salida al momento de ejecutar las lineas anteriores:

tinchicus@dbn001vrt:~/lenguajes/node.js/9/fibonacci$ npm run server

> fibonacci@0.0.0 server
> SERVERPORT=3002 node ./servidorfibo.js

(node:11110) [DEP0066] DeprecationWarning: OutgoingMessage.prototype._headers is deprecated
(Use `node --trace-deprecation ...` to show where the warning was created)
GET /fibonacci/10 200 71.127 ms - 22
GET /fibonacci/20 200 1121.640 ms - 24
GET /fibonacci/30 200 68084.036 ms - 26
Anuncios

Si bien usarlo mediante curl puede ser la forma mas sencilla de hacer las comprobaciones vamos a subir la vara un poco y para ello crearemos un cliente para conectarse,, para ello debemos crear en el raiz del directorio de la aplicacion otro nuevo archivo con el nombre de clientefibo.js y le agregaremos el siguiente codigo:

clientefibo.js

const http = require('http');

[
  "/fibonacci/20", "/fibonacci/15", "/fibonacci/10",
  "/fibonacci/9", "/fibonacci/8", "/fibonacci/7",
  "/fibonacci/6", "/fibonacci/5", "/fibonacci/4",
  "/fibonacci/3", "/fibonacci/2", "/fibonacci/1"
].forEach((path) => {
        console.log(`${new Date().toISOString()} solicitando ${path}`);
        var req = http.request({
                host: "localhost",
                port: process.env.SERVERPORT,
                path,
                method: "GET"
        }, res => {
                res.on('data', (chunk) => {
                  console.log(`${new Date().toISOString()} BODY: ${chunk}`);
                });
        });
        req.end();
});
Anuncios
Anuncios

Primero importaremos el modulo encargado del http, despues crearemos una serie de llamados al servidor, tal como vimos en el ejemplo anterior, y despues mediante forEach iremos accediendo a cada valor que queremos saber, primero mostraremos el momento de la solicitud, despues haremos un request donde le pasaremos el host, el puerto del servidor, el path (el valor que deseamos averiguar) y el metodo utilizado, y el siguiente sera para procesar la respuesta obtenida y en este caso tambien sera para mostrar el tiempo actual de respuesta y el valor, por ultimo terminamos la solicitud para iniciar la siguiente, recuerden que debemos tener el servidor corriendo en otra terminal, antes de probarlo debemos volver al archivo package.json y modificar la seccion de scripts de la siguiente forma:

  "scripts": {
    "start": "DEBUG=fibonacci:* node ./bin/www",
    "server": "SERVERPORT=3002 node ./servidorfibo.js",
    "cliente": "SERVERPORT=3002 node ./clientefibo.js"
  },
Anuncios

En este caso es similar al anterior porque le especificamos el mismo port pero llamamos al nuevo script, con esto podemos probarlo y para ello lo veremos en el siguiente video

Anuncios
Anuncios

Si observan no devolvio el mismo orden con el cual pasamos los datos, esto principalmente es debido a que es al orden que llegan los datos procesados, salvo el caso del 2 y el 1 el resto estan ordenados, y esto tambien es gracias a que usamos la version asincronica de la funcion y esto nos servira para crear el verdadero servicio backend, para esto debemos ir al directorio routes y crear un nuevo archivo con el nombre de fibo-rest.js y le agregaremos el siguiente codigo:

routes/fibo-rest.js

var express = require('express');
var router = express.Router();
var http = require('http');
const math = require('../math');

router.get('/', function(req, res, next) {
        if (req.query.fibonum) {
                var httpreq = http.request({
                        host: "localhost",
                        port: process.env.SERVERPORT,
                        path: `/fibonacci/${Math.floor(req.query.fibonum)}`,
                        method: 'GET'
                });
                httpreq.on('response', (response) => {
                        response.on('data', (chunk) => {
                                var datos = JSON.parse(chunk);
                                res.render('fibonacci', {
                                        title: "Calcular numeros fibonacci",
                                        fibonum: req.query.fibonum,
                                        fiboval: datos.result
                                });
                        });
                        response.on('error', (err) => { next(err); });
                });
                httpreq.on('error', (err) => { next(err); });
                httpreq.end();
        } else {
                res.render('fibonacci', {
                        title: 'Calcular numeros fibonacci',
                        fiboval: undefined
                });
        }
});

module.exports = router;
Anuncios
Anuncios

No es muy distinto a lo visto en otros posts, como siempre primero importaremos todos los modulos que necesitaremos,, entre ellos nuestro modulo para calcular el valor fibonacci, otro para el HTTPClient, y otro para hacer el ruteo, despues mediante el objeto de ruteo y el metodo get obtendremos ese simbolo y dentro tendremos un condicional donde verificara si pasamos un valor donde en caso de no pasarlo nos devolvera un valor vacio, en caso de pasarle uno lo primero que haremos sera crear un objeto para hacer la solicitud mediante el HTTPClient, en este caso le pasaremos todos los valores de nuestro servidor REST:

  • host, la direccion del servidor, en este caso el localhost
  • port, el puerto donde debe conectarse
  • path, el path que usaremos para hacer el calculo, igual que en el ejemplo anterior
  • method, el metodo de recuperacion de los datos
Anuncios

A este le aplicaremos un escuchador para el evento response, y a este le agregaremos otro para el evento data, la recepcion de datos, y tomaremos esta informacion para que muestre todos los datos recibidos en pantalla, el siguiente escuchador es para el caso de que ocurra un error, lo mismo tenemos despues pero este es para el caso del objeto del HTTPClient, para finalmente cerrar la solicitud, y al final exportamos este objeto, con esto tenemos el encargado del ruteo pero nos falta un par de modificaciones mas, la primera la haremos en app.js y buscaremos la siguiente linea para comentarla:

var fibonacciRouter = require('./routes/fibo-async');
Anuncios

Y debajo agregaremos la siguiente linea:

var fibonacciRouter = require('./routes/fibo-rest.js');
Anuncios

Ahora nuestro enrutador apuntara a este nuevo archivo, y para finalizar debemos ir al archivo package.json y modificaremos la seccion scripts de la siguiente manera:

  "scripts": {
    "start": "DEBUG=fibonacci:* node ./bin/www",
    "startrest": "DEBUG=fibonacci:* SERVERPORT=3002 node ./servidorfibo.js",
    "server": "DEBUG=fibonacci:* SERVERPORT=3002 node ./bin/www",
    "cliente": "DEBUG=fibonacci:* SERVERPORT=3002 node ./clientefibo.js"
  },
Anuncios

En este caso agregamos una nueva linea titulada como startest y esta llamara al script servidorfibo.js y modificaremos a server para que llame al www en bin pero a diferencia de start le asignaremos un puerto, ya veremos porque, nuestro siguiente paso sera primero iniciar al servidor REST mediante el siguiente comando:

$ npm run startrest
Anuncios

Y lo siguiente sera iniciar nuestro server y para ello usaremos el siguiente cmando:

$ npm run server
Anuncios

Con nuestro servidor levantado ya podremos utilizarlo como siempre, dado que solo modificamos la forma de rutear la informacion, vamos a ver como trabaja mediante el siguiente video

Anuncios

En el video podemos ver como trabaja nuestra aplicacion normalmente y a su vez vimos como inicie ambos servidores y en este caso pueden observar como cada uno procesa la informacion, pero en esta forma de trabajar podemos caer en un inconveniente de performance debido a que se quede sin memoria, para ello una opcion puede ser la siguiente:

"DEBUG=fibonacci:* SERVERPORT=3002 node ./servidorfibo.js --max_old_space_size 5000" 
Anuncios
Anuncios

Pero esto es solo para cuando tenemos problemas de memoria, por esta razon siempre debemos estar atentos a los problemas que puedan surgir y corregirlos de la mejor manera posible pero si este metodo lo comparamos con el asincronico no notaremos mucha diferencia, hasta puede ser mas practico pero en el caso de utilizarlo de esta forma podemos crear un grupo de servidores que se deddiquen solo a esta tarea y esto lo liberara el uso de nuestra CPU e inclusive hoy tenemos la posibilidad de poder utilizar al GPU para actuar como coprocesador, pero eso siempre quedara ajustado a la disponibilidad que tenemos para realizar tales o cuales tareas, tambien les dejo un par de herramientas para implementar REST:

  • Restify [http://restify.com/] ofrece un framework tanto de lado cliente como de servidor para transacciones REST
  • Loopback [http://loopback.io/] es un adicional de caracteristicas y esta desarrollado con Express
Anuncios

Antes de finalizar les dejo un link con un archivo donde estan todos los codigos tratados aqui sino tambien con todo los codigos del proyecto:

Anuncios

En resumen, hoy hemos visto como crear un servicio dde backend mediante REST, vemos primero como hacerlo mediante HTTPClient, para luego pasarlo a nuestra aplicacion y poder crear el servidor con el servicio de backend y como vincularlo a nuestra aplicacion para realizar el calculo, espero les sea de utilidad sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Anuncios

Donación

Es para mantenimento del sitio, gracias!

$1.50