3

Apuntes del Curso de Backend con Node.js

<h1>Curso de Backend con Node.js</h1> <h3>¿Qué es Node.js?</h3>
  • Node.js es un entorno de ejecución para JavaScript construido con el motor JavaScript V8 de Chrome. JavaScript es un lenguaje interpretado pero en
  • Node.js tenemos algo llamado el JIT Compiler que es una especie de monitor que optimiza fragmentos de código que son ejecutados frecuentemente.
<h3>Diferencias entre javascript y node.js</h3>
  1. Javascript
  • Tenemos el DOM. La interfaz web.
  • También tenemos el CSSOM
  • También el fetch API
  • Toda la capa del web storage
  • También el canvas API
  • Las APIs en general del navegador
  1. Node.js
  • Node tiene el módulo de HTTP para crear servidores
  • El módulo del sistema operativo para comunicarse con el SO
  • El módulo utilidades
  • El módulo debugger
  • En común
  • Librerías comunes streams
  • Eventos
  • Ecmascript modules
  • Consola
<h3>Arquitectura orientada a eventos</h3>

Uno de los paradigmas de programación en nodejs más populares es la arquitectura orientada a eventos, los eventos nos permiten manipular el código asíncrono de una mejor manera, para esto tenemos varias opciones para utilizar:

  • Callbacks
  • Promises
  • Async Await
  • Event Emitter
  • Readable
<h3>Eventos</h3>
  • data. Se dispara cuando recibe datos.
  • end. Se dispara cuando termina de recibir datos.
  • error. Se dispara cuando hay un error.
<h3>Funciones</h3>
  • pipe
  • unpipe
  • read
  • push
  • Writeable
<h3>Eventos</h3>
  • drain. Se dispara cuando emite datos.
  • finish. Se dispara cuando termina de emitir.
  • error. Se dispara cuando hay un error.

Funciones

  • write
  • end
<h3>Dúplex</h3>

implementa los métodos write y read a la vez.

<h3>Transform</h3>

es similar a Duplex pero con una sintaxis más corta.

<h3>Clusters y procesos hijos</h3>

Una sola instancia de Node.js corre un solo hilo de ejecución. Para tomar ventaja de los sistemas con múltiples core, necesitamos lanzar un cluster de procesos de Node.js para manejar la carga.
El módulo cluster nos permite la creación fácil de procesos hijos que comparten el mismo puerto del servidor. Veamos un ejemplo en código:

const cluster = require("cluster"); const http = require("http"); // Requerimos la cantidad de CPUs que tiene la maquina actual const numCPUs = require("os").cpus().length; if (cluster.isMaster) { console.log(Master ${process.pid} is running); // Si el cluster es maestro, creamos tantos procesos como numero de CPUS for (let i = 0; i < numCPUs; i++) { cluster.fork(); } // Si por alguna razón el cluster se finaliza hacemos un log cluster.on("exit", (worker, code, signal) => { console.log(worker ${worker.process.pid} died); }); } else { // Los diferentes workers pueden compartir la conexión TCP // En este caso es una servidor HTTP http .createServer((req, res) => { res.writeHead(200); res.end("hello world\n"); }) .listen(8000); console.log(Worker ${process.pid} started); }

Si corremos nuestro archivo de Node.js ahora compartirá el puerto 8000 con los diferentes workers:
$ node server.js Master 3596 is running Worker 4324 started Worker 4520 started Worker 6056 started Worker 5644 started

<h3>Request y Response objects</h3>

El objeto req (Request) en Express representa el llamado HTTP y tiene diferentes propiedades del llamado, como la cadena de texto query (Query params), los parámetros de la URL (URL params), el cuerpo (Body), los encabezados (HTTP headers), etc.

Para acceder al req basta con acceder al primer parámetro de nuestros router handlers (router middleware) ó middleware.

Como por ejemplo así lo hemos visto siempre:
app.get("/user/:id", function(req, res) { res.send("user " + req.params.id); });

Pero también funcionaria sin problemas:
app.get("/user/:id", function(request, response) { response.send("user " + request.params.id); });

Exploremos las propiedades más importantes

  • req.body
  1. Contiene los pares de llave-valor de los datos enviados en el cuerpo (body) del llamado (request). Por defecto es undefined pero es establecido cuando se usa algún “body-parser” middleware como body-parser y multer.

  2. En Postman cuando hacemos un request y enviamos datos en la pestaña Body, estos middlewares son los que nos ayudan a entender el tipo de datos que vamos a recibir en el req.body.

Aquí podemos ver como se pueden usar estos middlwares para establecer el valor del req.body:
`
const app = require(“express”)();
const bodyParser = require(“body-parser”);
const multer = require(“multer”);
const upload = multer(); // Para datos tipo multipart/form-data

app.use(bodyParser.json()); // Para datos tipo application/json
app.use(bodyParser.urlencoded({ extended: true })); // Para datos tipo application/x-www-form-urlencoded

app.post("/profile", upload.array(), function(req, res, next) {
console.log(req.body);
res.json(req.body);
});
`

Más información sobre los diferentes formatos que puede tener el body: https://developer.mozilla.org/es/docs/Web/HTTP/Methods/POST

req.params Esta propiedad contiene un objeto con las propiedades equivalentes a los parámetros nombrados en la ruta. Por ejemplo, si tenemos una ruta de la forma /user/:name entonces la propiedad name está disponible como req.params.name y allí podremos ver su valor. Supongamos que llamaramos a la ruta con /user/glrodasz, entonces el valor de req.params.name sería glrodasz. Este objeto por defecto tiene el valor de un objeto vacío {}. // GET /user/glrodasz req.params.name; // => "glrodasz"

req.query

Esta propiedad contiene un objeto con las propiedades equivalentes a las cadenas de texto query de la ruta. Si no hay ninguna cadena de texto query tendrá como valor por defecto un objeto vacío {}.

`
req.query.q;
// => “tobi ferret”

// GET /shoes?order=desc&shoe[color]=blue&shoe[type]=converse
req.query.order;
// => “desc”

req.query.shoe.color;
// => “blue”

req.query.shoe.type;
// => “converse”
`

Más información sobre los query strings en: https://es.wikipedia.org/wiki/Query_string y https://tools.ietf.org/html/rfc3986#section-3.4

<h3>Response Object</h3>

El objeto res representa la respuesta HTTP que envía una aplicación en Express.
Para acceder al res basta con acceder al segundo parámetro de nuestros router handlers (router middleware) o middleware.
Como por ejemplo así lo hemos visto siempre:
app.get("/user/:id", function(req, res) { res.send("user " + req.params.id); });

Pero también funcionaría sin problemas:
app.get("/user/:id", function(request, response) { response.send("user " + request.params.id); });

<h3>Exploremos los métodos más comunes</h3>
  • res.end()
    Finaliza el proceso de respuesta. Este método viene realmente del core de Node.js, específicamente del método response.end() de http.ServerResponse.

Se usa para finalizar el request rápidamente sin ningún dato. Si necesitas enviar datos se debe usar res.send() y

  • res.json().
  • res.end();
  • res.status(404).end();
    -res.json()
    Envía una respuesta JSON. Este método envía una respuesta (con el content-type correcto) y convierte el parámetro enviado a una cadena de texto JSON haciendo uso de JSON.stringify().
    El parámetro puede ser cualquier tipo de JSON, incluido un objeto, un arreglo, una cadena de texto, un boolean, número, null y también puede ser usado para convertir otros valores a JSON.
  • res.json(null);
  • res.json({ user: “tobi” });
  • res.status(500).json({ error: “message” });
  • res.send()
    Envía una respuesta HTTP. El parámetro body puede ser un objeto tipo Buffer,
    cadena de texto, un objeto, o un arreglo. Por ejemplo:
  • res.send(Buffer.from(“whoop”));
  • res.send({ some: “json” });
  • res.send("<p>some html</p>");
  • res.status(404).send(“Sorry, we cannot find that!”);
  • res.status(500).send({ error: “something blew up” });
<h3>Anatomía de una API Restful</h3>

REST (Representational State Transfer) es un estilo de arquitectura para construir web services, no es un estándar pero si una especificación muy usada.

<h4>Las peticiones HTTP van acompañadas de un “verbo” que define el tipo de petición:</h4>
  • GET. Lectura de datos.
  • PUT. Reemplazar datos.
  • PATCH. Actualizar datos en un recurso específico.
  • POST. Creación de datos.
  • DELETE. Eliminación de datos.

//Mockaroo* https://platzi.com/clases/1646-backend-nodejs/22029-estructura-de-una-pelicula-con-moockaru/

//crear la base del .gitignore en base a nuestro proyecto
http://gitignore.io/

Clean Architecture

  • PUT vs PATCH
  • PUT: Reemplazo total del recurso.
  • PATH: Actualización de algunos elementos del recurso.

Middleware: Es una pieza de software qué se encarga de unir otras piezas de software

<h3>Joi y Boom</h3>

Joi(Object Schema Validation). Sirve para validar que los datos que recibimos vengan en el formato adecuado.
Boom(HTTP-friendly error objects). Nos ayuda a imprimir errores comunes en peticiones HTTP de forma sencilla.

TDD(test driven development): En otras palabras crea primero las pruebas qué hay qué superar y después desarrolla en código para superar esas pruebas.

Escribe tu comentario
+ 2