¿Cómo podemos validar datos en el backend usando Joi?
Validar datos en el backend es crucial para garantizar la integridad y seguridad de nuestra aplicación. Uno de los casos de uso más comunes es asegurarse de que la información que recibimos del cliente sea correcta y esté completa antes de procesarla. Para ello, en esta clase se introduce el uso de la librería Joi, una herramienta potente para la validación de esquemas en JavaScript. A continuación, profundizamos en el proceso para implementar validaciones de datos usando Joi y Middlewares.
¿Qué es Joi y por qué es útil para la validación de datos?
Joi es una librería diseñada específicamente para validar objetos JavaScript. Permite definir un esquema para los datos esperados y ofrece diversas opciones de validación, como tipos de campos, requerimientos, límites de longitud, validaciones alfanuméricas, entre otros.
Facilita la representación de las restricciones de datos de manera declarativa.
Mejora la capacidad de reutilización y actualización de esquemas.
Reduce el riesgo de errores al asegurar que los datos cumplen con requisitos predefinidos antes de ser procesados.
¿Cómo configuramos Joi para validar nuestros datos?
Para empezar a usar Joi, primero debemos instalar la librería e importarla en nuestro proyecto. A continuación, definimos un esquema de validación conforme a los requerimientos de nuestra aplicación.
Este bloque de código define un esquema para tres campos: nombre, precio, e id. Cada campo tiene restricciones específicas:
nombre debe ser un string alfanumérico de entre 3 y 15 caracteres, y es requerido.
precio debe ser un número entero mínimo de 10 y también es requerido.
id debe seguir el formato GUID.
¿Cómo implementamos Joi en middlewares para validar dinámicamente?
Para hacer que la validación sea flexible y dinámica, se propone el uso de un middleware que pueda manejar diferentes propiedades de las solicitudes (requests). Aquí es donde entra en juego la creación de Middlewares dinámicos utilizando Closures.
Este middleware acepta un schema y una property (por ejemplo, body, params o query) y valida los datos de manera dinámica dependiendo de dónde se encuentren en la solicitud. Si la validación falla, se envía un error.
¿Cuáles son las mejores prácticas para usar Joi en el backend?
Centralizar esquemas de validación: Mantener los esquemas en archivos separados, como product.schema.js, facilita la gestión y evolución de las reglas de validación.
Utilizar el manejador de errores: Integrar Joi con un manejador de errores, como boom, organiza la respuesta del servidor ante datos inválidos.
Mantener las funciones puras y reutilizables: Las funciones de validación deben ser modulares para facilitar su uso en diferentes rutas y contextos.
¿Qué sigue después de implementar validaciones con Joi?
Después de haber implementado validaciones con Joi, el siguiente paso sería integrar y probar estas validaciones en las rutas de su aplicación. Esto garantizará la integridad de los datos en toda la aplicación y mejorará la experiencia del usuario al ofrecer mensajes de error claros y precisos. Continuar explorando las capacidades de Joi y los middleware en JavaScript enriquecerá tu comprensión y habilidades en el desarrollo de software robusto y seguro.
Este curso es genial, en otros validamos datos con Joi sin entender bien como funcionaba.
Si opino lo mismo, muy bien explicado
--No hay error.
El middleware: Fresco, tranquilo, siga 😎
🤣🤣🤣😁
Mi código + notas ja ja ja
const boom =require('@hapi/boom');// tiene que ser dinámicofunctionvalidatorHandler(schema, property){//clousuresreturn(req, res, next)=>{const data = req[property];// puede venir en body, params, o queryconst{ error }= schema.validate(data,{abortEarly:false});// para que envíe todos los errores juntosif(error){next(boom.badRequest(error));}next();//si no hay error sigue fresco tranquilo}}module.exports= validatorHandler;
Joi
Joi es la herramienta más poderosa para la validación de datos en JavaScript. Este módulo permite crear esquemas de datos usando un lenguaje simple, comprensible e intuitivo.
A la hora de interactuar con una API, es muy importante que se validen los datos tanto en el lado del servidor como en el del cliente para tener controlados posibles errores y la forma en la que se interactúa con la base de datos.
Anteriormente Joi pertenecía al ecosistema de Hapi, un framework para crear aplicaciones en Node, pero a partir de la versión 12.1.0 decidió dejar de formar parte de este framework y ser un paquete totalmente independiente, lo cual facilita aún más la integración con este.
Schema o DTO (Data Transfer objects), (objetos de Transferencia de datos)
Validar los datos que nos envían desde el cliente
Comando para instalar la libreria
npm i joi
Tengo una duda existencial, no especificamente de la clase.
En que casos se usa : la sintaxis const {error} = schema.validate(data);
En lugar de solo tener const error = schema.validate(data);
?
Si lees la documentación de Joi encuentras que al hacer un schema.validate(data) y fallar la validación ++te devuelve un objeto++ como el siguiente:
{value:{},error:'"username" is required'}
El profesor está accediando al valor de la propiedad error.
const{error}= schema.validate(data);
Es lo mismo que..
const error = schema.validate(data).error;
Apoyando un poco mas lo que dice nuestro compañero @luissberenguer lo que hizo el profe fue hacer Destructuring, aqui un ejemplo
Ahhhhh... ¿cómo le hacen para recordar para cada cosa una librería?
No lo hacen, en el curso con Kaufman, el lo menciona, 'no creas que me se todo de memoria, lo busque cuando prepare la clase'
Eso del comentario de abajo más los años de experiencia
Una excelente alternativa es express-validator 😁
Justo estaba buscando que era un DTO, Data Transfer Object, es un middleware para validar data entre otras cosas
Buen ejemplo caso práctico de dónde y cómo usar closures. No había encontrado una caso en dónde aplicarlos.
Existe un DTO más simple que hapi/joi e incluso más liviano que es yup
Una duda, por buenas practicas, lo correcto es validarlo en el backend o en el frontend?
Me imagino que la respuesta obvia será en el backend pero no es desgastante enviar multiples respuestas al frontend para que dependiendo del caso, muestre en la UI el error.
Creo que seria mejor en el frontend para hacer menos peticiones al servidor.
Haganme saber sus comentarios.
Desde mi punto de vista, si es posible, en ambos lugares, en el frontend como dices para mejorar la experiencia de usuario y "aliviar" carga a los servidores. Si algo ya se comprobó en el front como primer filtro ya no sería enviado al backend... (en teoría).
Pero... siempre hay personas (malintencionadas y no malintencionadas) que pueden vulnerar la seguridad de tu aplicación. Todo el frontend es "copiable" por así decirlo y manipulable, desde el envío de información inválida, hasta cambiar el comportamiento de un input requerido.
Por lo que en el Backendno es opcional hacer validaciones, el backend debe desconfiar de todo lo que venga del frontend, y si por alguna razón la validación del frontend falla, sigue la validación del lado del servidor.
seria mejor usar TypeScript ya el te resuelve estas validaciones, de tipo de dato y si es requerido o no y ya en el frontend se pueden hacer otras validaciones, con expresiones regulares
Aquí se crea un middleware de forma dinámica (se usa closure).
Si se recibe el schema, con schema.validate() se valida la información que se desea validar. La información viene de data, la cual viene de un request (body, params, query).
Si hay un error (no cumple con la validación), entonces se envía un error de tipo boom. Si no hay error, el servicio sigue (next()).
No conocia la librería Joi. Y yo validando los datos manualmente... 😒
Logro desbloqueado: Usar un closure de manera práctica en un caso real
Alguien podría ayudarme a saber que es y que hace un id uuid?
Lo vemos en el código como método .uuid() y el profesor dice que nuestro id tiene que ser de tipo uuid, ¿que significa?
El UUID (Universal Unique Identifier) es un formato que nos sirve como identificador y que una vez generado no se repite, es decir es único, este tipo de ids lo usan bases de datos como mongoDB y normalmente se ve así: