Conocer y comprender cómo se realizan las conexiones hacia los servidores a través de internet y sus implicaciones en el desarrollo de servidores

1

Bienvenida y presentación del curso

2

Qué es Node y cómo instalarlo

3

¿Qué son y cómo se usan las peticiones HTTP?

4

Métodos, cabeceras y estados

5

Cuerpo y query de la petición

Crear un servidor HTTP en Javascript, y comenzar a escuchar y responder peticiones desde un cliente .

6

Crear un servidor HTTP desde NodeJS

7

¿Cómo pueden venir las peticiones?

8

Recibir información desde el cliente: Body y Query

9

Información contextual: Leer las cabeceras

10

Tipos de respuesta: Vacía, plana, con datos y estructurada

11

Respuestas coherentes

12

Servir archivos estáticos

13

Errores: Cómo presentarlos e implicaciones en la seguridad

Comprender y desarrollar la arquitectura básica de un backend en NodeJS, y comunicarse entre módulos

14

Conceptualmente: Rutas, controladores y bases de datos

15

Rutas y capa de red: Responsabilidades y límites

16

Controladores: Definiendo la lógica de negocio

17

Almacenando la información en una base de datos

Utilizar una base de datos para definir, modelar, almacenar y recuperar la información de nuestra aplicación

18

Tipos de Bases de Datos: Relacionales y No Relacionales

19

Crear y Configurar tu Base de Datos con MongoDB

20

MongoDB: Almacenar y leer datos

21

MongoDB: Actualizar datos

22

MongoDB: Consultar datos

23

MongoDB: Eliminar Datos

24

Gestionar conexiones a la base de datos desde la API

Uso de entidades para crear aplicaciones escalables

25

Escalando la arquitectura: Múltiples entidades

26

Relacionando nuestras entidades

27

Cómo recibir ficheros desde NodeJS

28

Guardar el fichero en el servidor

Conocer el protocolo de websockets, e implementar comunicación cliente/servidor con SocketIO.

29

WebSockets: Qué son, por qué son interesantes y cómo usarlos

30

Manejo de Websockets con NodeJS

31

Conectar la API al servidor de WebSockets

Revisión de lo aprendido, y próximos pasos

32

Revisión y próximos pasos

33

Tips para escalar nuestro proyecto

No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Rutas y capa de red: Responsabilidades y límites

15/33
Recursos

Aportes 51

Preguntas 14

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Hola, Sergio,
.
Cualquier aplicación va a tener tres puntos de responsabilidad, que deben responder a tres preguntas:

¿Cómo me comunico con ella?
¿Qué hace?
¿Dónde y cómo se guardan los resultados?
.
La respuesta a estos tres puntos, corresponden a las tres capas que vamos a generar:
Capa de red (en inglés “network”)
Capa controladora (en inglés, “controller”)
Capa de almacenamiento (en inglés, “store”)
.
De esto hablo en profundidad en la clase anterior.
.
La primera capa es una capa de red, porque la conexión con la aplicación se hace a través del protocolo de comunicación en red HTTP. Es la responsable de comunicar al cliente HTTP con nuestro código del controlador.
.
Si recuerdas las primeras clases, verás que el protocolo HTTP construye una petición con una dirección (route), un verbo (method), unas cabeceras (headers) y un mensaje (body).
.
Por esto, cada uno de nuestros componentes, tendrá un archivo “network.js” encargado de traducir la petición del cliente HTTP a la acción que queremos realizar en nuestro controlador.
.
Así, lo que hace nuestro código (la funcionalidad) no está acoplado a unos requisitos de red, y puede ser reutilizado con otras fuentes de entrada (colas MQTT, una biblioteca externa, microservicios…).
.
La opción que planteas, llamarlo “interface” en lugar de network es también una opción válida. En caso de que tu carpeta se llame interface (o, quizá mejor, “interfaces”), llama a tu archivo “http-response.js” para poder generar nuevas interfaces de escucha o/y respuesta no HTTP.
.
¡Gracias!

No puedo responder a tu mensaje. Quería agradecer tu dedicación y tiempo tanto del curso como de las respuestas. Un saludo.

Clase que vale la pena repetir para estar claro de todo el proceso de conexion de la app...

Al aprender esto siento algo como lo que sentí con Redux en el Frontend. Una manera compleja de organización los datos que cuando la terminas integrando se transforma en una forma mas fácil de organizar el flujo de información. Y mas fácil para escalar.

Personalmente prefiero agrupar todo por componente entonces tendría /message
-/routes
-/controller
-/bd

para así encontrar fácilmente lo que necesite de algún componente

Hola, solo como aporte:

  1. En la carpeta --> network/routes.js no fue necesario requerir a express, al menos por el momento.
  2. otra forma de recibir el app desde server.js
module.exports = server => {
    server.use("/message", message);
}

Saludos!

Código escrito en ES:

server.js

import express from "express";
import { routes } from "./network/routes.js";

const app = express();

app.use(express.json());
app.use(express.urlencoded({extended : false}));
routes(app);

app.use('/app', express.static('public'));

app.listen(3000);

console.info('La app esta escuchando en http://localhost:3000');

network/routes.js

import message from "../components/message/network.js";

const routes = function (server) {
    server.use('/message', message);
}

export { routes }

components/message/network

import express from "express";
import { success, error } from "../../network/response.js";

const router = express.Router();

router.get('/',(req,res)=>{
    console.log(req.headers)
    res.header({
        "Custom-header":"Nuevo valor personalizado"
    });
    success(req, res, 'Lista de mensajes');
});

router.post('/',(req,res)=>{
    console.log(req.query);
    if(req.query.error == 'ok'){
        error(req, res, 'Error inesperado', 500, 'Es una simulación de errores');
    } else{
        success(req, res, 'Creado correctamente', 201);
    }
});

export default router 

No entiendo la estructura de network que estás planteando. Entiendo que lo único que puede ser considerado como “red” o “capa de red” es el app.listen y el socket.io que forman parte de la infraestructura.

No entiendo que tienen que ver las rutas HTTP con “network”.

El protocolo HTTP es un protocolo de la capa de aplicación, entendería que lo modularizaras en algo como “interface > response.js” para reutilizar con otras infraestructuras como Websockets, porque al final es parte de la interfaz hacia el cliente (humano o máquina). En el examen me ha llevado a la confusión.

Si alguien por aquí no entiende la diferencia de usar router o no, aquí les doy un enlace donde se explica a detalle y de forma sencilla: Learn to use router

Compañeros les dejo mi repositorio del curso, por si quieren ver la app terminada y sobre todo si quieren copiar algo de código, tiene unos ligeros cambios en los nombre de variables solamente. (Se los dejo porque en las clases que ya me sabia solo quería copiar código y avanzar)

https://github.com/johan-avila/chat-backend

La función “use” de express me parece ambigua, me cuesta saber qué hace exactamente.

yo lo ordené como

/messages
-/routes/index.js
-/controller/index.js
-/store/index.js
entonces al llamarlo con un require no es necesario hacer ‘…/components/messages/routes/index.js’ ya que por defecto toma el index.js de la carpeta y solo se lo llamaría como '…/components/messages/routes’
tambien funciona para las demas carpetas, por ahora me sirve.

Hola chicos llevo varios dias con un mismo problema, al momento de separar las rutas (segunda mitad del video) mi programa compila y todo pero al momento de abrirlo en el navegador y hacer el POST/GET con insomia me marca un " Cannot GET / ".

Ya revise que todo este exportado de la manera correcta y no lo puedo hacer funcionar, revise los demás problemas de mis compañeros y tampoco. Recurro a su sabiduría. les comparto captura de mi código



<h1>Resumen</h1>

Rutas y capa de red: Responsabilidades y límites


En el archivo components/message/network.js

const express = require('express')
const router = express.Router();

const response = require('./../../network/response');
const controller = require('./controller');

router.get('/', function (req, res) {
    console.log(req.headers);
    res.header({
        "custom-header":"myheader"
    });
    response.success(req, res, 'Lista de mensajes')
});

router.post('/', function (req, res) {
    const { user, message } = req.body; 
    controller.addMessage(user, message);
    
    res.send('hola')
});

module.exports = router;

Despues, debemos concentrar todas las rutas en un unico archivo

network/routes.js

const message = require('./../components/message/network')

const routes = function (server) {
    server.use('/message', message)
}

module.exports = routes;

Y el archivo server, queda asi

const express = require('express');
// Importar la funcion router
const router = require('./network/routes');


var app = express();
var port = 3000;

app.use(express.json())
app.use(express.urlencoded({ extended: true }))

router(app); // Uso de la funcion principal

app.use('/app',express.static(__dirname + '/public'));


app.listen(port, ()=> { console.log(`Servidor corriendo en el puerto ${port}`); }) 

Siento que el archivo network.js debería llamarse más bien “specificResponse.js” o algo así, pues se confunde la carpeta network con el archivo, y ya es de por sí complejo y confuso de entender

No me quedó clara la parte donde crea el archivo routes.js, ¿cómo hace para que funcione el enrutamiento desde el archivo network.js si en los métodos get y post está especificada la misma ruta “/”? Ahí me perdí.

Excelente explicación, el diagrama anterior me ayudo muchisimo. Otros profesores de Platzi deberían mostrar un diagrama de la arquitectura, para que uno como estudiante sepa cómo y en que vamos a estar trabajando.

Me confunde network como archivo dentro de component/message
y la carpeta network.

Routes y Response deberían estar dentro de network y no tener network dentro del components/message.

Me he perdido con esto.

Práctica:

Perfecto!

Si retiramos la importación de express en el archivo routes.js, la aplicación sigue funcionando ya que la instancia del servidor que pasamos por parámetro a la función viene con los métodos de express.

Mi pregunta es ¿será necesario importar express en este archivo?

Pequeño aporte para Platzi que explica por qué es beneficioso usar “use strict” en JavaScript y cómo configurar Visual Studio Code con la extensión “File Templates”:


Título: Importancia de “use strict” en JavaScript y Configuración en VSCode

Introducción:
En JavaScript, agregar la directiva "use strict"; al inicio de tus archivos es una práctica recomendada. Esta directiva activa un conjunto más estricto de reglas para el código, ayudando a prevenir errores comunes y a fomentar buenas prácticas de programación.

Beneficios de “use strict”:

  1. Errores más tempranos: Ayuda a identificar errores en tiempo de compilación en lugar de en tiempo de ejecución, facilitando la depuración.
  2. Mejora la seguridad: Al desactivar características propensas a errores, como variables no declaradas, “use strict” ayuda a escribir un código más seguro.
  3. Optimización del rendimiento: Algunos motores de JavaScript pueden realizar optimizaciones más efectivas cuando se usa “use strict”.

Configuración en VSCode con File Templates:
Para facilitar la inclusión automática de “use strict” en cada nuevo archivo JavaScript en VSCode, sigue estos pasos:

  1. Instala la extensión “File Templates”: Busca y agrega la extensión “File Templates” desde el menú de extensiones en VSCode.

  2. Crea un directorio .file-templates en la raíz de tu proyecto.

  3. Dentro de .file-templates, crea un archivo llamado javascript.js.

  4. Añade el siguiente contenido a javascript.js:

    "use strict";
    
    {{_cursor_}}
    
  5. Guarda el archivo. Ahora, cada vez que crees un nuevo archivo JavaScript, “use strict” se incluirá automáticamente.

Conclusión:
Utilizar “use strict” en tus proyectos de JavaScript es una práctica clave para mejorar la calidad y seguridad del código. La configuración simple en VSCode con la extensión “File Templates” facilita la adopción de esta buena práctica desde el principio de cada nuevo archivo.


Espero que encuentren útil este aporte para Platzi. ¡Buena suerte!

En el curso de Express con Nicolás Molina, vimos que es importante tener una ruta para antes de cada subruta de la API:

routes.js

const express = require("express");


const message = require("./../components/message/network");

function routes(app){
    const router = express.Router();
    app.use("/api", router);
    router.use("/message", message);
} 

module.exports = routes;

server.js

const express = require("express");
const bodyParser = require("body-parser");

const response = require("./network/response");

const router = require("./network/routes")

const app = express();
app.use(bodyParser.json());

const { config } = require("./config/config");

app.use("/app", express.static("public"));

router(app);

app.listen(config.port, console.log("Server on port ", config.port));

De ahora en más accedemos desde: localhost:3000/api/message

Para los que en el tramo final del video les aparece “Cannot POST /message” al intentar hacer las solicitudes. Recuerden retirar los “message” en las rutas del archivo “network.js”, puesto que en el archivo “routes.js” ya definieron como base para las peticiones de messages la ruta “/message”.

Así deje mi archivo network.js:

const express = require('express');

const response = require('../../network/response');

const router = express.Router();

router.get('/', (req, res) => {
    console.log(req.headers);
    res.header({
        "custom-header": "Nuestro valor personalizado",
    })
    res.send('Hola desde get');
})

router.post('/', (req, res) => {
    // res.send('Enviar mensaje');
    console.log(req.query);
    if (req.query.error == "ok") {
        response.error(req, res, 'Error inseperado', 500, 'Es solo una simulación de los errores');

    } else {
        response.success(req, res, 'Creado correctamente', 201);
    }
})

router.get('/', (req, res, message) => {
    // res.send('Lista mensaje');
    response.success(req, res, 'Lista de mensajes');
})

module.exports = router;

Yo estoy usando typescript para esto y lo hice asi

router.ts

import { Application } from "express";
import { Path as path } from "./paths";

import messageRouter from "../message/message.router";

export const router = (app: Application) => {
  app.use(path.message, messageRouter);
};

paths.ts

import { PathProps } from "./types";

export const Path: PathProps = {
  message: "/api/message",
};

message.router.ts

import { Router } from "express";
import { getMessage, sendMessage } from "./message.controller";
import { validateHandler } from "../../middleware/middleware";
import { createMessageDto } from "./message.dto";

const router = Router();

router.get("/", getMessage);
router.post("/", validateHandler(createMessageDto, "body"), sendMessage);

export default router;

message.controller.ts

import { NextFunction, Request, Response } from "express";

export const getMessage = (req: Request, res: Response, next: NextFunction) => {
  try {
    //const { headers } = req;
    //console.log(headers);

    const { message } = req.body;
    res.header({
      Authenticate: "TOKEN_JWT",
    });
    res.json({ message: message });
  } catch (error) {
    next(error);
  }
};

export const sendMessage = (
  req: Request,
  res: Response,
  next: NextFunction
) => {
  try {
    const { message } = req.body;
    res.status(201).send(message);
    res.json({ message });
  } catch (error) {
    next(error);
  }
};

estructura de carpetas

Me dejo de funcionar en esta clase el codigo 😦

Me tomo ver la clase 3 veces para entender y arreglar mis errores en mi código jaja

04/11/2022
components/message/network.js:

const express = require('express');
const response = require('../../network/response')

var app = express()
app.get('/', (req,res)=> {
    res.header({
        "custom-header": "mi propia cabecera personalizada"
    })
    response.sucess(req,res,'respuesta exitosa del get')
})

app.post('/', (req,res)=> {
    if (req.query.error === 'ok'){
        response.error(req,res, "mensaje de error",500,"detalles del error") 
    } else {
        response.sucess(req,res, "creado con exito",201)
    }
})

module.exports = app 

network/routes.js:

const express = require('express')
const message = require('../components/message/network')

const routes = function (server){
    server.use('/message', message)
}

module.exports = routes 

network/response.js:

exports.sucess = function (req,res,message,status){
    res.status(status || 200).send({
        error: '',
        body: message,
    })
}

exports.error = function (req,res, message,status,details){
    console.log("[response error] ",details)
    res.status(status || 500).send({
        error: message,
        body: '',
    }) 
}

server.js:

const express = require('express');
const routes = require('./network/routes')

const app = express()
app.use(express.json())
app.use(express.urlencoded({ extended: false }))

routes(app)

const port = 3000
app.listen(port)
console.log(`the application is listening on http://localhost:${port}`)

Me gusta mucho como se estructura el proyecto

Cuando define routes.js para crear la función que añade todas las rutas pasa como parámetro a server y dice que es el servidor de express.

Mi pregunta es si en ninguna parte has definido a server o este server tiene alguna relación con server.js o cuando definió el servidor express en lugar de colocar server colocó la const express o server es una variable global de node js que identifica al servidor.

Exelente aplicativo

Excelente clase!!

excelente Clase…Felicitaciones

excelente!

Yo no lo ordeno de esa forma pero es muy parecida

Responsabilidades=>rutas & límites=>capa de red

A organizar el código ya se lee mejor

puro orden y terner muy claro los nombres.

I got it.

Estoy intentado resolver un problema que tengo con el server.js. Al ejecutar la sentencia router(app) express se rompe. Solo en ese caso. Si vuelvo a un punto anterior el server levanta sin problemas. A alguien le paso??

Cuando has visto distintos videos para ver el mismo tema es algo confuso llevar el nombre de los archivos o carpetas porque cada quien le pone el nombre que quiere, sin embargo a Carlos le he entendido más que a ningún otro.

Que buena clase

Genial esto, separarlos y enlazarlos.

Esto es relevante, veamos si entendí:

El archivo server.js sigue siendo el archivo que lanza nuestro servidor web en node.js, este archivo tiene como archivo de dependencia routes.js (rutas)

Rutas:
routes.js, nos va ayudar a definir todas las rutas que está configurando el servidor, esto es para no definir más de una vez el router en el servidor en caso de que el proyecto crezca, en este caso lo estamos diferenciando, con server.use (‘laruta’,elcomponente)

El componente network:
network.js, va a ser la responsable de administrar todas las peticiones de HTTP y devolverlas al servidor.

exelente clase

este profesor es buenisimo

porque en el minuto 2:32 esta exportando el router que no se supone que eso viene de express y como es que las funciones get y post que se van al router alguien que me explique porfavor

Blew my mind!!!

En el archivo routes.js se ve claramente que la const express no se está utilizando.

Qué sentido tiene definir una constante que no se está utilizando allí o que efecto tiene el solo hecho de hacerle require. Es requerida y punto.

Cuando se tiene un componente la ruta se llama así:

module.exports = function (server) {
    server.use("/message", message);
}

¿Cómo se hace cuando hay mas componentes?, ¿se usa server.use por cada uno o todo crea un objeto para un solo server.use?

Si quieren ver algo parecido: Les invito a ver un repo que hice de un CRUD basico.
https://github.com/Tonnraus/Memories-Project

Me gusta mucho esta manera de ordenar los componentes