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

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

8/35
Recursos

El objeto request nos permite obtener datos de la petición recibida desde el cliente. El método pasado como parámetro para la creación de este objeto define si trabajaremos con GET o POST.

Proipiedades del request:

  • request.path
  • request.method
  • request.get
  • request.payload: es en esta propiedad donde recibimos los datos enviados con el método POST.

Ciclo de vida del objeto request, se refiere a los eventos que suceden durante la carga, existencia y descarga del objeto:

  • OnRequest
  • OnPreAuth
  • OnCredentials
  • OnPostAuth
  • OnPreHandler
  • OnPostHandler
  • OnPreResponse

Más información sobre el ciclo de vida del objeto request en el repositorio oficial del proyecto: Link

Código: Definimos rutas GET y POST para registrar usuarios y recibir
parámetros en el request.

Aportes 8

Preguntas 2

Ordenar por:

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

Mi aporte en el código

'use strict'

// Requerir el modulo de hapi (Framework)
const Hapi = require('@hapi/hapi')
// Requerir el plugin de hapi para servir archivos estaticos
const inert = require('@hapi/inert')
// Requerir el plugin de hapi para gestionar el motor de plantillas
const vision = require('@hapi/vision')
const path = require('path')

// Configurar el servidor de nuestra aplicación. En un contenedor (Docker) si marca error colocar 0.0.0.0 (todos)
const server = Hapi.server({
  port: process.env.PORT || 3000,
  host: 'localhost',
  // Definir propiedades generales para todas las rutas. (En este caso indico que las rutas que requieran archivos estáticos, se servirán desde la carpeta public)
  routes: {
    files: {
      relativeTo: path.join(__dirname, 'public')
    }
  }

})

// Definicion de función para inicializar el proyecto. Intenamnete hay tareas asincronas
async function init() {

  try {
    // Registrar los plugins que hapi va a necesitar (en este caso servir archivos estaticos)
    await server.register(inert)
    // Registrar plugin para gestionar el motor de plantillas
    await server.register(vision)

    // Configurar nuestro motor de plantillas. Usará handlebars y cuando invoquemos una vista automáticamente buscará una con extensión hbs (no hace falta especificarlo). Debe buscar a partir del directorio actual, las vistas se encuentran en views y se activa compatibilidad con layouts, los cuales se encuentran en layouts
    server.views({
      engines: {
        hbs: require('handlebars')
      },
      relativeTo: __dirname,
      path: 'views',
      layout: true,
      layoutPath: 'layouts'
    })

    // Definición de rutas (indicar el método HTTP, URL y controlador de ruta)
    // Se declaran después del plugin ya que las rutas hacen uso del misom para devolver archivos estáticos
    server.route({
      method: 'GET',
      path: '/',
      handler: (req, h) => {
        // El plugin de vision inyecta el metodo view al objeto h para renderizar una vista con el motor de plantillas configurado en la aplicación
        return h.view('index', {
          title: 'Home'
        })
      }
    })

    /**
     * Rutas para el registro de usuarios
     * 
     * el objeto request permite recuperar los datos de la petición. 
     * sus propiedades son path, method, 
     * params, query, get, payload (PUT/POST)
     * 
     * El objeto request tiene un ciclo de vida en HapiJS
     * https://github.com/hapijs/hapi/blob/master/API.md#request-lifecycle
     */
    server.route({
      method: 'GET',
      path: '/register',
      handler: (req, h) => {
        return h.view('register')
      }
    })

    server.route({
      method: 'POST',
      path: '/create-user',
      handler: (req, h) => {
        // Mostrar en consola el cuerpo de la petición
        console.log(req.payload)
        return 'Usuario creado satisfactoriamente'
      }
    })

    // Ruta para servir archivos estáticos asociados (img/css/js)
    server.route({
      method: 'GET',
      path: '/{param*}',
      handler: {
        directory: {
          path: '.',
          redirectToSlash: true
        }
      }
    })

    // Arrancar el servidor de Hapi
    await server.start()
    console.log(`Servidor lanzado en: ${server.info.uri}`)
  } catch (error) {
    console.error(error)
    // Salir de nodeJS con un código de error (1), 0 es un código de exito
    process.exit(1)
  }
}

// Inicializar el proyecto
init();

dejo el link del repo en github por si alguien lo necesita:

https://github.com/platzi/hapi-overflow

Que interesante la simplicidad en su desarrollo.

porque el campo de correo exige que los datos ingresados contengan arroba , ¿en que parte del codigo se encuentra esto ?

Tambien puede resumir el registro de hapi de esta forma:

await server.register(require('@hapi/inert'))
'use strict'

const Hapi = require('hapi');
const handlebars = require('handlebars');
const config = require('./config');
const inert = require('inert');
const path = require('path');
const vision = require('vision');

const server = Hapi.server({
  port: config.port,
  host: config.host.process,
  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'
    })

    server.route({
      method: 'GET',
      path: '/',
      handler: (req, h) => {
        return h.view('index', {
          title: 'home',
        });
      }
    });

    server.route({
      method: 'GET',
      path: '/register',
      handler: (req, h) => {
        return h.view('register', {
          title: 'Registro',
        });
      }
    });

    server.route({
      method: 'POST',
      path: '/create-user',
      handler: (req, h) => {
        console.log(req.payload)
        return 'Usuario creado'
      }
    });
  
    server.route({
      method: 'GET',
      path: '/{param*}',
      handler: {
        directory: {
          path: '.',
          index: ['index.html']
        }
      }
    });

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

  console.log(`Servidor lanzado en: http://${config.host}:${config.port}`);
}

init();

Me agrada como queda utilizando pug en el view engine…

extends ./layout/layout

block content
  .container.mt-4
    .card.mb-3
      .card-header
        h3 Signup here
    
      .card-body
        .row
          .col
            form(
              method="POST"
              action="/new-user"
            )
              +formGroup('name', 'text')(pattern='.{3,}')
              +formGroup('email', 'email')(pattern=emailPattern)
              +formGroup('password', 'password')(pattern='.{6,}')

              .text-center.mt-5
                button.btn.btn-primary.btn-block(type="submit") Send

block footer
  include ./partials/footer
block scripts
  include ./partials/scripts