El error de el minuto 06:55 se debe a que escribió mal return, el puso retrun si es posible hacerlo en una sola linea
return reject('Los datos son incorrectos');
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
Bienvenida y presentación del curso
Qué es Node y cómo instalarlo
¿Qué son y cómo se usan las peticiones HTTP?
Métodos, cabeceras y estados
Cuerpo y query de la petición
Crear un servidor HTTP en Javascript, y comenzar a escuchar y responder peticiones desde un cliente .
Crear un servidor HTTP desde NodeJS
¿Cómo pueden venir las peticiones?
Recibir información desde el cliente: Body y Query
Información contextual: Leer las cabeceras
Tipos de respuesta: Vacía, plana, con datos y estructurada
Respuestas coherentes
Servir archivos estáticos
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
Conceptualmente: Rutas, controladores y bases de datos
Rutas y capa de red: Responsabilidades y límites
Controladores: Definiendo la lógica de negocio
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
Tipos de Bases de Datos: Relacionales y No Relacionales
Crear y Configurar tu Base de Datos con MongoDB
MongoDB: Almacenar y leer datos
MongoDB: Actualizar datos
MongoDB: Consultar datos
MongoDB: Eliminar Datos
Gestionar conexiones a la base de datos desde la API
Uso de entidades para crear aplicaciones escalables
Escalando la arquitectura: Múltiples entidades
Relacionando nuestras entidades
Cómo recibir ficheros desde NodeJS
Guardar el fichero en el servidor
Conocer el protocolo de websockets, e implementar comunicación cliente/servidor con SocketIO.
WebSockets: Qué son, por qué son interesantes y cómo usarlos
Manejo de Websockets con NodeJS
Conectar la API al servidor de WebSockets
Revisión de lo aprendido, y próximos pasos
Revisión y próximos pasos
Tips para escalar nuestro proyecto
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Aportes 44
Preguntas 12
El error de el minuto 06:55 se debe a que escribió mal return, el puso retrun si es posible hacerlo en una sola linea
return reject('Los datos son incorrectos');
Aquí les dejo una propuesta del código utilizando async-await
post(async (req, res) => {
try{
const fullMessage = await controller.addMessage(req.body.user, req.body.message)
response.success(req, res, 201, fullMessage)
}catch(error){
response.error(req,res,null,error)
}
})
Hola Devs:
-Me propuse como reto apartir de esta clase, realizar todo el proyecto con TypeScript, es mi primera vez con TS, pero quiero darle, si alguien mas se anima, les dejare en cada clase apartir de ahora, el link del commit exacto de la clase, asi pueden checar mi solucion usando TS.
-Aca les dejo mi avance:
Capa de Network del componente Message
Capa del Controller del componente Message
-Estoy abierto a mejoras o PR, soy nuevo con TS por si ven alguna mejora, aca les dejo el commit exacto de esta clase: Click Aqui
"Tambien pueden checar la config que use para trabajar con TS, por si quieren checar"
-Recuerda, #NuncaParesDeAprender 💚
Ahora ya le encuentro utilidad al curso de Fundamentos de JS, muy buena clase
Hola que tal, estoy utilizando las promesas con async/await
Network:
router.post('/', async (req, res) => {
try {
const body = await Controller.addMessage(req.body.user, req.body.message);
await response.success(req, res, { error: null, body }, 200);
} catch (error) {
console.error(`[POST/message]: ${error}`);
await response.error(req, res, { error: 'Error Interno', body: null }, 400);
}
});
Controller:
const addMessage = (user, message) => new Promise((resolve, reject) => {
const fullMessage = {
user,
message,
date: new Date()
};
if (!user || !message) {
reject(new Error('se requiere user y message'));
return;
}
resolve(fullMessage)
});
Les comparto los apuntes que llevo hasta ahora, tengo varias funcionalidades que he visto en la documentación y algunos apuntes, espero les sirva 😃
server.js
//Modulos node-express
const express = require('express')
const bodyParser = require('body-parser')
//Modulos locales
const response = require('./network/response')
const router = require('./network/routes')
//Creando la app
const app = express()
//variables de la app
app.set('port', 3000)
//Middlewares
app.use(express.json())
app.use(express.urlencoded({ extended: false }))
//! Router siempre debe de ir al final
//? Ya no vamos a usar el app.use(router)en su vez usaremos el router app
//Rutas
//?Usaremos las rutas de network
router(app)
app.use('/app', express.static('public'))
//Empezando el servidor en el puerto $port
app.listen(app.get('port'))
console.log(`La aplicacion está corriendo en el puerto ${app.get('port')}`)
routes.js
//? Recibe desde server la app (server) y establece la función padre de un router
//? De cada una de las rutas después llama a messages/network quienes envian el mensaje de respuesta
const express = require('express')
const message = require('../components/messages/network')
const routes = function (server) {
server.use('/message', message)
}
module.exports = routes
network.js
const express = require('express')
const router = express.Router()
// Modulos locales
const response = require('../../network/response')
const controller = require('./controller')
//!||
router.get('/', (req, res) => {
//console.log(req.headers)
console.log(req.body)
console.log(req.query)
res.header({
Valor: 'Personalizado',
})
//?Enviamos un send desde otras funciones en otro archivo (response)
if (req.query.error == 'ok') {
response.error(
req,
res,
'Tu peticion por url no puede ser completada',
403,
'Parametro rechazado',
)
} else {
response.success(req, res, 'Hola desde get')
}
})
//!||
router.post('/', (req, res) => {
//? Enviamos info de el req a el archivo -> controller lo que retorna una promesa
//? Después recibimos la response de el archivo response y enviamos success o error
controller // -> Controller
.addMessage(req.body.user, req.body.message)
.then(fullMessage => {
response.success(req, res, fullMessage, 201, 'Datos recibidos') // -> Response
})
.catch(() => {
response.error(
// -> Response error
req,
res,
'Informacion invalida',
403,
'El usuario no ha introducido datos correctos',
)
})
res.header({
//-> Envía un header a el cliente
Valor: 'Personalizado',
})
})
//!||
router.delete('/', (req, res) => {
//console.log(req.headers)
console.log(req.body)
console.log(req.query)
res.header({
Valor: 'Personalizado',
})
//?Enviamos un send desde otras funciones en otro archivo (response)
if (req.query.error == 'ok') {
response.error(
req,
res,
'Tu peticion por url no puede ser completada',
403,
'Parametro rechazado',
)
} else {
response.error(
req,
res,
'hola desde delete aqui te retornaré un 404 :B',
403,
'Trataron de usar delete',
)
}
})
module.exports = router
controller.js
//?Este archivo recibe informacion desde la network
function addMessage(user, message) {
return new Promise((resolve, reject) => {
if (!user || !message) {
console.error('[MessageController] No hay usuario o mensaje')
reject('Los datos son incorrectos')
return false
}
const fullMessage = {
user: user,
message: message,
date: new Date(),
}
console.log(fullMessage)
resolve(fullMessage)
})
}
module.exports = {
addMessage,
}
responses.js
//? Este archivo es usado dentro de el enrutador para enviar respuestas
//* Server <- routes <- network <- responses
exports.success = function (req, res, message, status) {
res.status(status || 200).send(message)
}
exports.error = function (req, res, message, status, details) {
console.log(details)
res.status(status || 404).send(`Mensaje de error :( "${message}"`)
}
Por fin entiendo más lo del controlador. En el trabajo era tan difícil entender como se conectaba a la capa de presentación.
¡Muchas gracias Profe! 😬👍
Si quieres crear una hora y fecha mas legible, usa esto:
const fullMessage = {
user,
message,
date: new Date().toLocaleString()
27/02/2021, 12:49:46 p.m.
}
Cuando trabajamos con javascript y estamos creando un objeto, podemos omitir el nombre de la variable si el valor es igual a la variable es mas claro esto con un ejemplo
const fullMessage = { user, message, date: new Date() }
Esto va devolver
{ user: 'Nicolas', message: 'perrano', date: 2020-09-06T19:32:07.650Z }
Les dejo la manera de hacerlo con try catch funcionado en el caso que tiren error a proposito
en Network
router.post('/message/', async (req, res) => {
try {
const fullMessage = await controller.addMessage(req.body.user, req.body.message);
if (fullMessage) {
response.success(req, res, fullMessage, 200);
} else {
throw Error;
}
} catch (error) {
response.error(req, res, 'error en servidor', 500, 'detalles del error: ninguno, solo probando');
}
// res.send({ parametro: req.params, query: req.query });
});
en controller
const addMessage = async (user, message) => {
//
try {
if (!user || !message) {
console.log('no hay usuario o mensaje');
throw Error('no hay nada');
}
console.log(user);
console.log(message);
const fullMessage = {
message: message,
user: user,
date: new Date(),
};
return fullMessage;
} catch (error) {
console.log('Entra en error ', error);
return false;
}
};
Me causa un poco de conflicto, vengo de C# con .net y el controlador es usualmente aquella clase o elemento que recibe la peticion, una vez ahi dependiendo la arquitectura, manda la informacion a un servicio a ser procesada, y despues a un repo para ser almacenada (asi es como suelo trabajar) me causa un poco de conflicto llegar y que haya rutas que reciben la peticion, un controlador que procesa la informacion
controladores=>lógica de negocio
En Controller irán todas las funcionalidades asociada a cada ruta, o cada feature.
¿Que pasa si en la parte de la promesa lo hubiese dejado de la siguiente manera?
.
function addMessage(user, msg) {
return new Promise(function(resolve, reject){
if (user && msg) {
// code goes here...
resolve('Everything goes right');
} else {
// code goes here...
reject('Oh no an error has occurred');
}
});
}
.
Aun que me imagino que por estar trabajando en Node.js tenemos que seguir el patro de Error First. Sin embargo me quede con esa duda, ¿que opinas Carlos?
Les dejo el codigo con async await
router.post('/', async (req, res) => {
try {
const fullMessage = await controller.addMessage(req.body.user, req.body.message);
// req, res, message, status
response.success(req, res, fullMessage, 201);
} catch (error) {
// req, res, message, status, details
response.error(req, res, error, 400, 'Error in controller')
}
});
porque se puede generar este error?
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:526:11)
at ServerResponse.header (/mnt/d/documentos/programacion/curso_node/node_modules/express/lib/response.js:771:10)
at ServerResponse.send (/mnt/d/documentos/programacion/curso_node/node_modules/express/lib/response.js:170:12)
at ServerResponse.json (/mnt/d/documentos/programacion/curso_node/node_modules/express/lib/response.js:267:15)
at ServerResponse.send (/mnt/d/documentos/programacion/curso_node/node_modules/express/lib/response.js:158:21)
at Object.exports.success (/mnt/d/documentos/programacion/curso_node/netwokr/response.js:2:31)
at /mnt/d/documentos/programacion/curso_node/components/message/network.js:24:14
at Layer.handle [as handle_request] (/mnt/d/documentos/programacion/curso_node/node_modules/express/lib/router/layer.js:95:5)
at next (/mnt/d/documentos/programacion/curso_node/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/mnt/d/documentos/programacion/curso_node/node_modules/express/lib/router/route.js:112:3)
Para pasar parámetros sin importar su orden, los podemos pasar a través de un objeto.
function save({ user, message }) {}
uso:
save({ message, user })
No tenemos que preocuparnos por el orden si no solo por cuáles son los que se deben pasar.
Les el codigo con async await
router.post('/', async (req, res) => {
try {
const fullMessage = await controller.addMessage(req.body.user, req.body.message);
// req, res, message, status
response.success(req, res, fullMessage, 201);
} catch (error) {
// req, res, message, status, details
response.error(req, res, error, 400, 'Error in controller')
}
});
¿Existe alguna dependencia en NPM que ayude a hacer los logs más sencillo? Encuentro poco eficiente tener que escribir [messageController] en los logs para saber de dónde vienen. ¿Habrá alguna dependencia que haga esto or nosotros?
Espectacular.
const express = require('express');
const response = require('../../network/response');
const controller = require('./controller');
const router = express.Router();
router.get('/', (req, res) => {
console.log(req.headers);
res.header({
"custom-header": "Nuestro valor personalizado"
})
response.success(req, res, 'Error inesperado');
});
router.post('/', (req, res) => {
controller.addMessage(req.body.user, req.body.message)
.then( (fullMessage) => {
response.success(req, res, fullMessage, 201);
})
.catch( e => {
response.error(req, res, 'Informacion invalida', 400, 'Error en el controller');
})
});
module.exports = router;
Qué gran curso!! Con esta sola clase se me han resuelto muchas dudas que tenía de cursos más avanzados de node.js. Grande Carlos!
2:298 la macro Copiar línea. Para copiar la línea actual hacía arriba o abajo. Windows y Linux. Shift + Alt + ↓
A modo de edición podrían poner un bloque abajo, cuando ocupan macros, para aprender como escribir código mas rápido y eficiente. Ya que el profesional lo hace de manera intuitiva y nos interesa.
Creamos un nuevo archivo controller.js dentro de la carpeta message el cual contendrá toda la lógica de negocio del componente message y será exportado como un modulo
components/message/controller.js:
function addMessage (user,message){
const fullMessage = {
user,
message,
date: new Date(),
}
return new Promise((res,rej)=> {
if (!user || !message){
rej('data incorrecta')
return
}
res(fullMessage)
})
}
module.exports = {
addMessage,
}
luego procedemos a importar el controlador en el archivo network.js en el componente message y a modificar el POST recibiendo un user y un message en el cuerpo del body del request
{
"user": "Juan",
"message": "Hello people"
}
como el retorno del controller es una promesa, modificamos la lógica para que todo funcione correctamente
components/message/network.js:
const express = require('express');
const response = require('../../network/response')
const controller = require('../message/controller')
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)=> {
controller.addMessage(req.body.user, req.body.message)
.then(fullMessage => response.sucess(req,res, fullMessage,201))
.catch(error => response.error(req,res, error,500,"detalles del error"))
})
module.exports = app
si hacemos una petición POST a la url “/message” con el cuerpo del body
{ "user": "juan", "message": "Hello people" }
vemos como respuesta de parte del servidor
{
"error": "",
"body": {
"user": "Juan",
"message": "Hello people",
"date": "2022-11-04T19:37:13.352Z"
}
}
si hacemos la misma petición pero no le mandamos nada en el cuerpo del body, vemos como respuesta de parte del servidor
{
"error": "data incorrecta",
"body": ""
}
formato util para fechas:
date: new Date().toLocaleString()
devuelve:
date: '26/10/2022, 3:02:41 p. m.'
o toman el formato que les sea mas util de:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
pero digamos que las promesas en funciones sincronas no son tan utiles para eso esta try catch para validar si algo que deberia estar en el try este ready si no cae al catch esta mal implementada esta clase ya que no explica la realidad de las promesas si nos vamos a principios SOLID los route aplicarlos a lo que indica ya que la mayoria de esa logia debe estar en el controller
Así podrían usar el formato hh:mm:ss dd/mm/yy para ver mejor las fechas.
const date = new Date();
date:
date.getHours() +
":" +
date.getMinutes() +
":" +
date.getSeconds() +
" " +
date.getDate() +
"/" +
(date.getMonth() + 1) +
"/" +
date.getFullYear().toString().slice(-2),
Este curso es excelente
muy interesante la clase
Ahora viendo que envía la hora y fecha con los mensajes, me parece útil hacerlo también con los errores, para saber en que momento fue que se generaron.
El req.body siempre me daba undefind por mas que le pase correctamente el json en el body. A todo este estaba utilizando Postman para hacer los llamados a la API, pero cuando cambie a insomnia me llegaron correctamente los POST. No se a que se debe esto, pero si alguien quiere probar eso tal vez le sirva
Muy interesante este curso.
Práctica:
Excelente clase Tocayo!!
Tengo una duda. Estuve probando qué sucedería si hubiera un error dentro del método then, por ejemplo procesando la respuesta, y me pareció que podría manejar mejor el flujo de mi programa si manejo la respuesta de la siguiente manera:
controller.addMessage(req.body.user, req.body.message)
.then(
resolve => {
console.log(10/a) // Error bestial de ejemplo
response.success(req, res, 201, 'Mensaje creado correctamente')
},
error => {
console.log(10/a) // Error bestial de ejemplo
response.error(req, res, 400, "Algunos datos pueden estar incompletos", error)
}
)
.catch(e => {
response.error(req, res, 500, "Error interno del servidor", e)
})```
Entonces en el caso que tuviera un error dentro de mi resolve o error, especialmente en desarrollo sería más fácil detectarlo (en este ejemplo console.log(10/a)), y catch me devolvería el error que tuve finalmente, y no le estaría echando la culpa al usuario de haber ingresado datos incorrectos, cuando la culpa fue mía durante el procesamiento de la respuesta.
Si esto es una mala práctica o no fuera necesario me gustaría saber por qué. Muchas gracias.
8:55 — Cuando utilizo Insomnia no me da el mismo resultado. Me dice:
{ "error": "Informacion invalida", "body": "" }
Estoy seguro de tener los códigos bien escritos.
Ayuda, por favor.
Buenas noches, Disculpen tengo un problema al ejecutar el post el cliente RES que estoy usando me retorna este error:
pre>SyntaxError: Unexpected token u in JSON at position 4<br> at JSON.parse (<anonymous>)<br> at parse (/home/jorge/Documents/WORKSPACE/nodeJsIni/node_modules/body-parser/lib/types/json.js:89:19)<br> at /home/jorge/Documents/WORKSPACE/nodeJsIni/node_modules/body-parser/lib/read.js:121:18<br> at invokeCallback (/home/jorge/Documents/WORKSPACE/nodeJsIni/node_modules/raw-body/index.js:224:16)<br> at done (/home/jorge/Documents/WORKSPACE/nodeJsIni/node_modules/raw-body/index.js:213:7)<br> at IncomingMessage.onEnd (/home/jorge/Documents/WORKSPACE/nodeJsIni/node_modules/raw-body/index.js:273:7)<br> at emitNone (events.js:106:13)<br> at IncomingMessage.emit (events.js:208:7)<br> at endReadableNT (_stream_readable.js:1064:12)<br> at _combinedTickCallback (internal/process/next_tick.js:138:11)</pre>
</body>
Muy buena clase!
Mi promesa no deja de caer en el catch, aunque nunca se ejecuta el reject, ¿a alguien le sucede lo mismo? Se que no cae en el reject porque no se ejecuta el console.error, pero por alguna razón sigue ejecutándose el catch.
Tengo este error, alguien sabe por qué?
El proyecto esta en git?
Asi que me he animado hahahah.
Aqui os dejo un video en YT que dice como hacer el Setup:
https://www.youtube.com/watch?v=zRo2tvQpus8
genial la clase!, genial!
Gracias profe!!
Puedes usar el object destructuring, para pasar el user y message de forma mas clara:
router.post('/',(req,res)=>{
const {body:{user,message}} = req
controller.addMessage(user, message)
.then((fullMessage)=>{
response.success(req,res,200,fullMessage)
})
.catch(()=>{
response.error(req,res,400,'Error')
})
})
#nuncaparesdeaprender
crear promesa para validar el controlador
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?
o inicia sesión.