Tu primera experiencia con Node.js

1

¿Dónde aprender backend con Node.js actualizado?

2

Todo lo que aprenderás sobre backend con Node.js

3

¿Qué es Node.js?

4

¿Qué es Node.js y para qué sirve?

5

Diferencias entre Node.js y JavaScript

6

Resumen: Diferencias Nodejs y Javascript

7

Instalación de Node.js

8

Arquitectura orientada a eventos

9

Node.js para la web

Manejo y uso de Streams con Node.js

10

Introducción a streams

11

Readable y Writable streams

12

Duplex y Transforms streams

Uso de utilidades de Node.js

13

Sistema operativo y sistema de archivos

14

Administrar directorios y archivos

15

Consola, utilidades y debugging

16

Clusters y procesos hijos

Crea tu primer proyecto en Express.js

17

¿Qué es Express.js y para qué sirve?

18

Creando tu primer servidor con Express.js

19

Request y Response Objects

Aprende a crear un API con REST

20

Anatomía de una API Restful

21

Estructura de una película con Moockaru

22

Implementando un CRUD en Express.js

23

Métodos idempotentes del CRUD

24

Implementando una capa de servicios

Cómo conectarse con librerías externas en Express.js

25

Creación de una BD en MongoAtlas

26

Conexión a MongoAtlas una instancia de MongoDB

27

Conexión con Robot3T y MongoDB Compass a una BD

28

Implementación de las acciones de MongoDB

29

Conexión de nuestros servicios con MongoDB

Conoce como funcionan los Middleware en Express.js

30

¿Qué es un middleware? Capa de manejo de errores usando un middleware

31

Manejo de errores asíncronos y síncronos en Express

32

Capa de validación de datos usando un middleware

33

¿Qué es Joi y Boom?

34

Implementando Boom

35

Implementando Joi

36

Probar la validación de nuestros endpoints

37

Middlewares populares en Express.js

Implementa tests en Node.js

38

Creación de tests para nuestros endpoints

39

Creación de tests para nuestros servicios

40

Creación de tests para nuestras utilidades

41

Agregando un comando para coverage

42

Debugging e inspect

Despliega tu primera aplicación en Express.js

43

Considerando las mejores prácticas para el despliegue

44

Variables de entorno, CORS y HTTPS

45

¿Cómo implementar una capa de manejo de caché?

46

¿Cómo contener tu aplicación en Docker?

47

Despliegue en Now

Conclusiones

48

¿Qué aprendiste en este curso?

No tienes acceso a esta clase

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

Implementando Joi

35/48
Recursos

Aportes 40

Preguntas 13

Ordenar por:

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

Hay cambiado la documentación de joi para validar el schema, actualmente resolví el problema que me aparecio en esa parte con el siguiente código:

const boom = require('@hapi/boom');
const joi = require('@hapi/joi');

function validate(data, schema){
    const { error } = joi.object(schema).validate(data);// cambio en la validación
    return error;
}
function validateHandler(schema, check = 'body'){
    return function(req, res, next){
        const err = validate(req[check], schema);
        err ? next(boom.badRequest(err)): next();
    }
}

module.exports = validateHandler;

Con la nueva version me funciono de esta manera

const boom = require('@hapi/boom')
const joi = require('@hapi/joi')

const validate = (data, schema) => {
  const { error } = joi.object(schema).validate(data);
  return error
}

const validationHandler = (schema, check = 'body') => {
  
  return (req, res, next) => {
    const error = validate(req[check], schema)

    error? next(boom.badRequest(error)) : next()
  }
}

module.exports = validationHandler

Actualización de @hapi/joi --> joi

Actualmente el mensaje del autor de @hapi/joi recomienda utilizar joi.

para actualizarlo, les dare unos pasos muy sencillos, es la forma mas elegante que pude razonar, espero les sirva. Documentacion de Joi

Paso 1 - Desinstalar

// Desinstalar  hapi/joi 
npm uninstall @hapi/joi

Paso 2 - Instalar

// Instalar joi
npm install joi

Paso 3 - utils/middleware/validationHandler.js

const boom = require('@hapi/boom');
const joi = require('joi');

function validate(data, schema) {
	// If schema is not a joi schema convert to a joi schema object otherwise return schema
	schema = !joi.isSchema(schema) ? joi.object(schema) : schema;
	const { error } = schema.validate(data);
	return error;
}

function validationHandler(schema, data = 'body') {
	return function (req, res, next) {
		const error = validate(req[data], schema);
		error ? next(boom.badRequest(error)) : next();
	};
}

module.exports = validationHandler;

Paso 4 utils/schemas/movies.js

const joi = require('joi');

const movieIdSchema = joi.string().regex(/^[0-9a-fA-F]{24}$/);
const movieTitleSchema = joi.string().max(80);
const movieYearSchema = joi.number().min(1888).max(2077);
const movieCoverSchema = joi.string().uri();
const movieDescriptionSchema = joi.string().max(300);
const movieDurationShema = joi.string().min(1).max(300);
const movieContentRatingShema = joi.string().max(5);
const movieSourceSchema = joi.string().uri(); 
const movieTagsSchema = joi.array().items(joi.string().max(50));

const createMovieSchema = joi.object({
	title: movieTitleSchema.required(),
	year: movieYearSchema.required(),
	cover: movieCoverSchema.required(),
	description: movieDescriptionSchema.required(),
	duration: movieDurationShema.required(),
	contentRating: movieContentRatingShema.required(),
	source: movieSourceSchema.required(),
	tags: movieTagsSchema,
});

const updateMovieSchema = joi.object({
	title: movieTitleSchema,
	year: movieYearSchema,
	cover: movieCoverSchema,
	description: movieDescriptionSchema,
	duration: movieDurationShema,
	contentRating: movieContentRatingShema,
	source: movieSourceSchema,
	tags: movieTagsSchema,
});

module.exports = {
	movieIdSchema,
	createMovieSchema,
	updateMovieSchema,
};

Paso 5 routes/movies.js

const express = require('express');
const MoviesService = require('../services/movies');

const {
	movieIdSchema,
	createMovieSchema,
	updateMovieSchema,
} = require('../utils/schemas/movies');
const validationHandler = require('../utils/middleware/validationHandler');

function moviesApi(app) {
	const router = express.Router();
	app.use('/api/movies', router);

	const moviesService = new MoviesService();

	router.get('/', async function (req, res, next) {
		const { tags } = req.query;
		try {
			const movies = await moviesService.getMovies({ tags });
			res.status(200).json({
				data: movies,
				message: 'movies listed',
			});
		} catch (err) {
			next(err);
		}
	});

	router.get(
		'/:movieId',
		validationHandler({ movieId: movieIdSchema }, 'params'),
		async function (req, res, next) {
			const { movieId } = req.params;

			try {
				const movies = await moviesService.getMovie({ movieId });

				res.status(200).json({
					data: movies,
					message: 'movie retrieved',
				});
			} catch (err) {
				next(err);
			}
		}
	);

	router.post(
		'/',
		validationHandler(createMovieSchema),
		async function (req, res, next) {
			const { body: movie } = req;
			try {
				const createdMovieId = await moviesService.createMovie({ movie });

				res.status(201).json({
					data: createdMovieId,
					message: 'movie created',
				});
			} catch (err) {
				next(err);
			}
		}
	);

	router.put(
		'/:movieId',
		validationHandler({ movieId: movieIdSchema }, 'params'),
		validationHandler(updateMovieSchema),
		async function (req, res, next) {
			const { movieId } = req.params;
			const { body: movie } = req;

			try {
				const updatedMovieId = await moviesService.updateMovie({
					movieId,
					movie,
				});

				res.status(200).json({
					data: updatedMovieId,
					message: 'movie updated',
				});
			} catch (err) {
				next(err);
			}
		}
	);

	router.delete(
		'/:movieId',
		validationHandler({ movieId: movieIdSchema }, 'params'),
		async function (req, res, next) {
			const { movieId } = req.params;

			try {
				const deletedMovieId = await moviesService.deleteMovie({ movieId });

				res.status(200).json({
					data: deletedMovieId,
					message: 'movie deleted',
				});
			} catch (err) {
				next(err);
			}
		}
	);
}

module.exports = moviesApi;

Listo con esto finalizas, ya puedes usar la version mas actualizada hasta el momento 17.3.0

Si tienen problemas para validar, dejo un ejemplo con los cambios mínimos a implementar
En lugar de retornar un objeto plano, se retorna un objeto de tipo joi

const createMovieSchema = joi.object({
  title: movieTitleSchema.required(),
  year: movieYearSchema.required(),
  cover: movieCoverSchema.required(),
  description: movieDescriptionSchema.required(),
  duration: movieDurationSchema.required(),
  contentRating: movieContentRatingSchema.required(),
  source: movieSourceSchema.required(),
  tags: movieTagsSchema
});

En la sección del middleware de validación, el schema es el que debe validar ahora la información

function validate(data, schema) {
  // Esta verificación es necesaria, ya que cuando validamos el id pasado como parámetro, pasamos un objeto plano, por tanto, lo convertimos a uno de tipo joi. (de lo contrario no tenemos acceso al metood validate
  if (!schema.isJoi) {
    schema = joi.object({ ...schema });
  }
  console.log(data);
  const { error } = schema.validate(data);
  return error;
}

Espero haber auxiliado a mas de uno.

Hola Devs:
Aqui tienen, asi no pasan lucha como yo:
/^[a-zA-Z0-9]{3,30}$/

Importante, hay un problema con la versión

.
Si seguiste el tutorial y no te funcionó, tal vez tu versión se instaló mal, para arreglarlo sólo hacer:
.

~ npm uninstall --save @hapi/joi
~ npm install --save @hapi/joi@15.0.3

Esta es la actualización que hay que hacer para que funcionen las validaciones

const boom = require('@hapi/boom')
const joi = require('@hapi/joi')

const validate = (data, schema) => {
  const { error } = schema.validate(data)
  return error
}

const validationHandler = (schema, check = 'body') => {
  
  return (req, res, next) => {
    const error = validate(req[check], schema)

    error? next(boom.badRequest(error)) : next()
  }
}

module.exports = validationHandler

Estamos colocando el middleware validation handler entre la ruta y el middleware final. Asi mismo podemos colocar varios middleware.

¡Esto es lo que querias decir con la explicación del middleware con la metafora de la población y el agua! colocamos varios intermediarios antes de la acción HTTP final.

ahh!!! también hay una nueva forma para los schemas asi

// Un objeto
const schema = Joi.object({
    a: Joi.string()
});

// Validación
const { error, value } = schema.validate({ a: 'a normal string' });

// Un string fácilmente cualquier tipo de valor
const schema2 = Joi.string().min(10);

// Validación 
const { error, value } = schema2.validate('Hello');

Recomendación:

Estas clases donde se implementan librerías de 3ros, hay que verlas, para aprender lo que se puede hacer y la razón por la que se hace así. El codigo como tal no es lo mas relevante ya que la implementacion puede variar de una version a otra.

Definitivamente, mongoose es una belleza

Chicos para el error de validación con Joi, lo único que tiene que modificar es :
Con la versión 17.1.1:

function validate(data, schema) {
  const { error } = joi
    .object(schema)
    .validate(data, { errors: { stack: true } });
  return error;
}

Cualquier duda me escriben

Ahora hay que usar npm install joi

y en el código

const boom = require("@hapi/boom");
const Joi = require("joi");

function validate(data, schema) {
  const { error } = Joi.object(schema).validate(data);
  return error;
}```

Hola,como mecionan los compañeros,si tienes problemas con la impementacion de joi debido a una actualizacion,puedes hacer esto.

Create un schema de joi

const joi = require('@hapi/joi');

const movieCreate = joi.object().keys({
  name: joi.string().min(5).required().error((errors) => new Error('EL nombre es requerido y debe tener minimo 5 caracteres')),
  type: joi.string().min(5).required().error((errors) => new Error('EL tipo  es requerido y debe tener minimo 5 caracteres')),
})

Adicionalmente puedes pasar un error personalizado en la funcion error.

EL VALIDADOR DE SCHEMA

const boom = require('@hapi/boom');

function validation(schema,data) {
 //Aca recibes el esquema de joi y ejecutamos su metodo validate donde le pasaras la data(objeto) de la peticion que recibiremos del la peticion,este  y otros mas estan disponible en los schemas,puedes darle un viztazo a la doc 
  const  { error } = schema.validate(data);
  return error;
}

function dataValidation(schema, check = 'body' ) {
  return function(req, res, next) {
    const error = validation(schema, req[check])
    error ? next(boom.badRequest(error)) : next();
  }
}

En la nueva versión de Joi ya no existe la función de joi.validate, ahora se hace de otra forma así que si usas a partir de la versión 16 este video ya no ayuda

¿Qué diferencia hay entre express-validator y Joi?

aca les dejo la definicion de los schemas:

const movieIdSchema = joi.string().regex(/^[0-9a-fA-F]$/)

const movieTitleSchema = joi.string().max(80)
const movieYearSchema = joi.string().min(1888)
const movieCoverSchema = joi.string().uri()
const movieDescriptionSchema = joi.string().max(280)
const movieDurationSchema = joi.string().min(1).max(300)
const movieContentRatingSchema = joi.string().max(5)
const movieSourceSchema = joi.string().uri()
const movieTagsSchema = joi.array().items(joi.string())

Si usas Typescript algo como Joi ya no sería necesario ?

En vez de Joi se podria usar mongoose?

Me vine a esta lección solo por la actualización pero valió la pena

Hola! Como estan? Si tienen problemas con las validaciones, como en mi caso, donde mi consola retornaba algo asi:
validationHandler({ movieId: movieIdSchema }, ‘params’),
^

TypeError: validationHandler is not a function. Bien, no se preocupen! en 2021, la manera de solucionar este error es cambiarlo el codigo de Validation Handler, por lo tanto, lo unico que deben hacer, es dejarlo asi:

//priemro hara la validacion, y la retornare falsa ya que no quiero validar nada, asi todo pasa como agua.
const boom = require('@hapi/boom')
const joi = require('@hapi/joi')

const validate = (data, schema) => {
  const { error } = schema.validate(data)
  return error
}

const validationHandler = (schema, check = 'body') => {
  
  return (req, res, next) => {
    const error = validate(req[check], schema)

    error? next(boom.badRequest(error)) : next()
  }
}

module.exports = validationHandler

npm i @hapi/joi esta obsoleto. Usen npm i joi. 😄

2077 el año punk

Forma de hacer usando [Yup] lo recomiendo mucho mas porque es mas ligero que el package que usa el profesor(https://github.com/jquense/yup#arrayoftype-schema-schema)

**/utils/middleware/validationHandler.js
**

// Packages
const boom = require('@hapi/boom');
const { object } = require('yup');

function validate(data, schema) {
  const error = object(schema).validateSync(data);
  return error;
}

function validationHandler(schema, check = 'body') {
  return (req, res, next) => {
    const error = validate(req[check], schema);
    error ? next(boom.badRequest(error)) : next();
  };
}

module.exports = { validationHandler };

/utils/schemas/movies.js

// Packages
const { string, number, array } = require('yup');

const movieIdSchema = string().matches(/^[0-9a-fA-F]{24}$/);

const titleShema = string().max(80);
const yearSchema = number().min(1888).max(2077);
const coverSchema = string().url();
const descriptionSchema = string().max(300);
const durationSchema = number().min(1).max(300);
const contentRatingSchema = number().max(5);
const sourceShema = string().url();
const tagsSchema = array(string());

const createMovieSchema = {
  title: titleShema.required(),
  year: yearSchema.required(),
  cover: coverSchema.required(),
  description: descriptionSchema.required(),
  duration: durationSchema.required(),
  contentRating: contentRatingSchema.required(),
  source: sourceShema.required(),
  tags: tagsSchema,
};

const updateMovieSchema = {
  title: titleShema,
  year: yearSchema,
  cover: coverSchema,
  description: descriptionSchema,
  duration: durationSchema,
  contentRating: contentRatingSchema,
  source: sourceShema,
  tags: tagsSchema,
};

module.exports = {
  movieIdSchema,
  createMovieSchema,
  updateMovieSchema,
};

/routes/movies.js —> es el mismo código que escribe el profesor en la clase, no requiere ninguna configuración adicional por el uso de Yup

Hay una librería muy útil que nos da la validación para los id de mongodb https://www.npmjs.com/package/joi-objectid

Joi esta deprecada, encontré esta alternativa express-validator, no se si conocen alguna otra

Recomiendo mas el uso de yup, también es un validador de Schema.

Crear los schema es como crear una interfaz en ty, no?

A quien le apetece ayudarme a ofrecer un proyecto para un negocio que acaba de abrir en mi calle? Una pasteleria, les dejo su IG @umamita_ y este es su web, hay que ofrecerles un backend con Stripe y NodeJS para que ella pueda cobrar sus productos, es una pasteleria creativa y vegana. Umamita Website Le quiero meter mano a Nodejs y Stripe y quizás a Vuejs

Un buen gigachad nunca se rinde!💚

Código!

si no quiero utilizar Joi, podría utilizar typeScript y utilizar los middlewares como antes?

Joi y Bom, me gusta la forma en que te facilitan la vida para las validaciones de entradas y salidas.

Con la validación de JOI, veo en consola que se alcanza a conectar con MongoDB.

Si es Schema no es validado correctamente no debería conectarse con Mongo.

No es asi?

Que buen guiño a Cyberpunk 2077 😄

Excelente ver y entender mas a fondo las cosas que uno ve en otros cursos. Por ejemplo todo esto tambien se puede hacer con GraphQL. Ahora ya voy entendiendo mejor muchas cosas!

Esto últimamente me empieza volar la cabeza, veo mucha documentación por delante pero está genial. Estamos creando un backend.
Sería mucho más fácil usando Mongoose pero creo que es bueno saber como se hace todo originalmente

😃

😄