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:

Los aportes, preguntas y respuestas son vitales para aprender en comunidad. Reg铆strate o inicia sesi贸n para participar.

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/[email protected]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 }, 鈥榩arams鈥),
^

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

馃槂

馃槃