Introducción

1

Qué necesitas para este curso y qué aprenderás sobre Node.js con Hapi

2

Conceptos principales de hapi y creación de nuestro primer servidor

3

Breve historia y estado actual

Creando un sitio básico con Hapi

4

El objeto h, response y sus herramientas

5

Uso de plugins - Contenido estático

6

Plantillas con Handlebars

7

Renderizado de vistas - Layout y template del home

8

Recibiendo parámetros en una ruta POST - Creación del registro

9

Definir una mejor estructura con buenas prácticas en Hapi

10

Validando la información - Implementando Joi

11

Introducción a Firebase

12

Creando un modelo y guardando en firebase

13

Implementando el login y validación del usuario

14

Autenticación de usuarios - Cookies y estado

15

Manejando errores

16

Visualización de errores

17

Controlar el error 404 en inert y el error de validación

18

Repaso - Creación del modelo y controlador para preguntas

19

Repaso - Creación de las rutas para crear preguntas

20

Listar las últimas preguntas en el home

Aplicacion de conceptos avanzados

21

Enrutamiento avanzado - visualizando una pregunta

22

Enrutamiento avanzado - respondiendo una pregunta

23

Generando la lógica de la plantilla según si es creador o contribuidor

24

Métodos de servidor - respuesta correcta

25

Usando métodos de servidor

26

Manejo del caché - Agregando el home al caché

27

Procesamiento de archivos - Aceptando imágenes

28

Logging con Good - Monitoreando el servidor

29

Creación de plugins - Teoría

30

Creación de plugins - Implementando un API REST

31

Estrategías de autenticación - Asegurando el API REST

32

Seguridad básica - Asegurando el servidor contra CSRF

33

Seguridad básica - Asegurando el servidor contra XSS

Herramientas de desarrollo

34

Depuración del proyecto

35

Ecosistema de Hapi

No tienes acceso a esta clase

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

Validando la información - Implementando Joi

10/35
Recursos

La validación de los datos suministrados por el usuario puede hacerse tanto en el frontend como en el backend, incluso puede hacerse en ambos lados, lo cual se recomienda.

Para hacer la validación de información en el backend, Hapi cuenta con un módulo llamado Joi que ofrece múltiples condiciones de validación, como: tipo de dato, mínimos y máximos, condiciones personalizadas, etc.

Joi nos permite generar validación de un esquema específico en Hapi en el mismo momento en que se definen las rutas.

Luego de instalar y requerir el módulo en el arhivo routes.js será necesario agregar la propiedad options que contiene a su vez validate y luego payload, en esta caso porque los datos serán recibidos por POST, allí definimos entonces las condiciones de validación para cada dato esperado.

Aportes 16

Preguntas 2

Ordenar por:

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

Ojo el esquema de validación actual para el payload es bajo un joi object

        {
            method: 'POST',
            options: {
                validate: {
                    payload: joi.object({
                        name: joi.string().required().min(3),
                        email: joi.string().email().required(),
                        password: joi.string().required().min(6)
                    })
                }
            },
            path: '/create-user',
            handler: user.createUser
        }

Mi aporte en el código
Al día de hoy es importante instalar hapi, sus módulos y plugins desde

npm i @hapi/hapi @hapi/inert @hapi/joi @hapi/vision

Por otra parte, es posible que en la versión de hapi 18.4 y joi 16.1.4 no funcione la validación tal como lo explica el profesor. Dejo un ejemplo completo actualizado hasta Septiembre 2019

// Requerir módulo para validación de datos en el backend
const Joi = require('@hapi/joi')

// Requerir modulos de controlador de ruta
const siteController = require('./controllers/site')
const userController = require('./controllers/user')

// Declarar conjunto de rutas y asociar su respectivo controlador de ruta
const routes = [
  {
    method: 'GET',
    path: '/',
    handler: siteController.index
  },
  {
    method: 'GET',
    path: '/register',
    handler: userController.register
  },
  {
    // Los datos enviados a esta ruta deben cumplir con cierto esquema de validación. Ṕara ello se agrega dentro de sus opciones la validación del payload (body request)
    // Cada esquema define los criterios que debe cumplir un campo para pasar la validación 
    method: 'POST',
    path: '/create-user',
    handler: userController.createUser,
    options: {
      validate: {
        payload: Joi.object({
          email: Joi.string().email().required(),
          name: Joi.string().required().min(3),
          password: Joi.string().required().min(6)
        })
      }
    }
  },
  {
    // Ruta para servir archivos estáticos asociados (img/css/js)
    method: 'GET',
    path: '/{param*}',
    handler: {
      directory: {
        path: '.',
        redirectToSlash: true
      }
    }
  }
];

module.exports = routes

Si les aparece un error como el siguiente:

Error: Cannot set uncompiled validation rules without configuring a validator

Deben de definir el payload como un Joi.Object

   options: {
      validate: {
        payload: Joi.object({
          name: Joi.string()
            .required()
            .min(3),
          email: Joi.string()
            .email()
            .required(),
          password: Joi.string()
            .required()
            .min(6)
        })
      }
    },

Estoy impresionado con la facilidad de conectar el backend con el frontend

https://www.npmjs.com/package/joi ya fue deprecado, para el curso si funciona, pero para hacer una aplicación ya deberían de usar el actualizado. Ahora esta en https://github.com/hapijs/joi

Buenas tardes, que plugin utilizan en el browser para que la respuesta se muestre en una forma grafica amigable??

En mi browser se presenta asi… **{“statusCode”:400,“error”:“Bad Request”,“message”:“Invalid request payload input”}

Si llegan a tener un error como este

Lo que deben hacer es agregar en index.js, un required para tener a Joi en dicho archivo, y requerirlo como una propiedad dentro del configurador de server.

   const Hapi = require('@hapi/hapi')
const handlebars = require('handlebars')
const inert = require('@hapi/inert')
const vision = require('@hapi/vision')
const path = require('path')
const routes = require('./routes')
const Joi = require('joi')

const server = Hapi.server({
  port: process.env.PORT || 8080,
  host: 'localhost',
  routes: {
    files: {
      relativeTo: path.join(__dirname, 'public')
    }
  }
})

async function init () {
  try {
    await server.register(inert)
    await server.register(vision)

    server.views({
      engines: {
        hbs: handlebars
      },
      relativeTo: __dirname,
      path: 'views',
      layout: true,
      layoutPath: 'views/layout'
    })
    server.validator(Joi)
    server.route(routes)

    await server.start()
  } catch (error) {
    console.error(error)
    process.exit(1)
  }

  console.log(`Servidor lanzado en: ${server.info.uri}`)
}

me sale este error
AssertionError [ERR_ASSERTION]: Invalid schema content:
at Object.exports.schema (C:\Users\Gloria Lopez\gloria\cursos\carreraBackend_JS\hapi\platzi-overFlow\node_modules\Hapi\node_modules\joi\lib\cast.js:55:10)
at internals.Object.keys (C:\Users\Gloria Lopez\gloria\cursos\carreraBackend_JS\hapi\platzi-overFlow\node_modules\Hapi\node_modules\joi\lib\types\object\index.js:358:35)
at Object.exports.schema (C:\Users\Gloria Lopez\gloria\cursos\carreraBackend_JS\hapi\platzi-overFlow\node_modules\Hapi\node_modules\joi\lib\cast.js:36:29)
at internals.Object.keys (C:\Users\Gloria Lopez\gloria\cursos\carreraBackend_JS\hapi\platzi-overFlow\node_modules\Hapi\node_modules\joi\lib\types\object\index.js:358:35)
at Object.exports.schema (C:\Users\Gloria Lopez\gloria\cursos\carreraBackend_JS\hapi\platzi-overFlow\node_modules\Hapi\node_modules\joi\lib\cast.js:36:29)
at internals.Object.keys (C:\Users\Gloria Lopez\gloria\cursos\carreraBackend_JS\hapi\platzi-overFlow\node_modules\Hapi\node_modules\joi\lib\types\object\index.js:358:35)
at Object.exports.schema (C:\Users\Gloria Lopez\gloria\cursos\carreraBackend_JS\hapi\platzi-overFlow\node_modules\Hapi\node_modules\joi\lib\cast.js:36:29)
at module.exports.internals.Any.root.compile (C:\Users\Gloria Lopez\gloria\cursos\carreraBackend_JS\hapi\platzi-overFlow\node_modules\Hapi\node_modules\joi\lib\index.js:159:25)
at Object.exports.compile (C:\Users\Gloria Lopez\gloria\cursos\carreraBackend_JS\hapi\platzi-overFlow\node_modules\Hapi\lib\validation.js:21:49)
at C:\Users\Gloria Lopez\gloria\cursos\carreraBackend_JS\hapi\platzi-overFlow\node_modules\Hapi\lib\route.js:195:43 {
generatedMessage: false,
code: ‘ERR_ASSERTION’,
actual: false,
expected: true,
operator: ‘==’,
path: ‘name.$_root.alternatives’
}

En este momento ya hubo actualizaciones a @hapi por lo que la importación del modulo joi sería:

const Joi = require('joi');

Para la implementación que estoy haciendo con typescript, pug y utilizando es6 modules:

import Joi from 'joi';

El zip de la implementación del proyecto lo encuentran en:
archivo zip

y cualquier feedback al repo es bienvenida:
repo github

Si tienen un error con joi, de este tipo:

AssertionError [ERR_ASSERTION]: Invalid schema content:                                                                                                                      
    at Object.exports.schema (E:\Documents\03 Cursos y Universidad\01 Platzi\00 Platzi Master\learning path\02 Curso Node con Hapi\platzi-overflow\node_modules\hapi\node_mod
ules\joi\lib\cast.js:55:10)                                                                                                                                                  
    at internals.Object.keys (E:\Documents\03 Cursos y Universidad\01 Platzi\00 Platzi Master\learning path\02 Curso Node con Hapi\platzi-overflow\node_modules\hapi\node_mod
ules\joi\lib\types\object\index.js:358:35)                                                                                                                                   
    at Object.exports.schema (E:\Documents\03 Cursos y Universidad\01 Platzi\00 Platzi Master\learning path\02 Curso Node con Hapi\platzi-overflow\node_modules\hapi\node_mod
ules\joi\lib\cast.js:36:29)                                                                                                                                                  
    at internals.Object.keys (E:\Documents\03 Cursos y Universidad\01 Platzi\00 Platzi Master\learning path\02 Curso Node con Hapi\platzi-overflow\node_modules\hapi\node_mod
ules\joi\lib\types\object\index.js:358:35)                                                                                                                                   
    at Object.exports.schema (E:\Documents\03 Cursos y Universidad\01 Platzi\00 Platzi Master\learning path\02 Curso Node con Hapi\platzi-overflow\node_modules\hapi\node_mod
ules\joi\lib\cast.js:36:29)                                                                                                                                                  
    at module.exports.internals.Any.root.compile (E:\Documents\03 Cursos y Universidad\01 Platzi\00 Platzi Master\learning path\02 Curso Node con Hapi\platzi-overflow\node_m
odules\hapi\node_modules\joi\lib\index.js:159:25)                                                                                                                            
    at Object.exports.compile (E:\Documents\03 Cursos y Universidad\01 Platzi\00 Platzi Master\learning path\02 Curso Node con Hapi\platzi-overflow\node_modules\hapi\lib\val
idation.js:21:49)                                                                                                                                                            
    at E:\Documents\03 Cursos y Universidad\01 Platzi\00 Platzi Master\learning path\02 Curso Node con Hapi\platzi-overflow\node_modules\hapi\lib\route.js:195:43            
    at Array.forEach (<anonymous>)                                                                                                                                           
    at module.exports.internals.Route._setupValidation (E:\Documents\03 Cursos y Universidad\01 Platzi\00 Platzi Master\learning path\02 Curso Node con Hapi\platzi-overflow\
node_modules\hapi\lib\route.js:193:60) {                                                                                                                                     
  generatedMessage: false,                                                                                                                                                   
  code: 'ERR_ASSERTION',                                                                                                                                                     
  actual: false,                                                                                                                                                             
  expected: true,                                                                                                                                                            
  operator: '==',                                                                                                                                                            
  path: '$_root.alternatives'                                                                                                                                                
}                                                                                                                                                                            
[nodemon] app crashed - waiting for file changes before starting...                                                                                                          

Se soluciona instalando:

npm install @hapi/hapi

instalen

npm i @hapi/joi

ya que el paquete que usan en el surso ya fue deprecado

npm i joi -S

Realize la clase con los nombres normales de los modulos sin @hapi/ y funcionaron perfecto solo hay que colocar al payload el joi.object cabe aclarar que trabaje en linux

    {
        method: 'POST',
        options: {
            validate: {
                payload: {
                    name: Joi.string().required().min(3),
                    email: Joi.string().email().required(),
                    password: Joi.string().required().min(6)
                }
            }
        },
        path: '/create-user',
        handler: user.createUser
    } ,

Muchas gracias por la explicación de esta extensión instructor Adrian, funciona mientras se sigan los pasos y también se añada el Joi.object después del payload.