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

You don't have access to this class

Keep learning! Join and start boosting your career

Aprovecha el precio especial y haz tu profesión a prueba de IA

Antes: $249

Currency
$209
Suscríbete

Termina en:

2 Días
16 Hrs
4 Min
26 Seg

Definir una mejor estructura con buenas prácticas en Hapi

9/35
Resources

In order to have a better organization of the files of our project, and considering that we are working with the MVC architecture, we will make a first refactoring of the code.

We create the /controllers directory to place the site and user controllers of our project. We pass the definition of the routes to its own routes.js module as an array that we will export later. We distribute the handlers associated to each view in the definition of the routes to the controller file for each context, either site or user. We require the handlers from the routes module, and finally we import the routes definition from the index.js and associate them to the server with server.route(routes).

The root of the general structure would be for the moment:
-/public
-/controllers
-/views
-routers.js
-index.js

Contributions 9

Questions 3

Sort by:

Want to see more contributions, questions and answers from the community?

Mi aporte en el código
Archivo index.js

'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')

// Requerir archivo de rutas
const routes = require('./router')

// 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 plugins de hapi para servir archivos estaticos
    await server.register(inert)
    // Registrar plugin para gestionar el motor de plantillas
    await server.register(vision)

    // Configurar nuestro motor de plantillas.
    server.views({
      engines: {
        hbs: require('handlebars')
      },
      relativeTo: __dirname,
      path: 'views',
      layout: true,
      layoutPath: 'layouts'
    })

    // Registrar archivo de rutas en la aplicación
    server.route(routes)
    // 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();

Archivo router.js

// 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
  },
  {
    method: 'POST',
    path: '/create-user',
    handler: userController.createUser
  },
  {
    // Ruta para servir archivos estáticos asociados (img/css/js)
    method: 'GET',
    path: '/{param*}',
    handler: {
      directory: {
        path: '.',
        redirectToSlash: true
      }
    }
  }
];

module.exports = routes

Archivo userController.js

// Definición de controladores de ruta

function register(req, h) {
  return h.view('register')
}

function createUser(req, h) {
  console.log(req.payload)
  return 'Usuario creado satisfactoriamente'
}

module.exports = {
  register,
  createUser
}

Archivo siteController.js

// Definición de controlaadores de ruta

function index(req, h) {
  return h.view('index', {
    title: 'Home'
  })
}

module.exports = {
  index
}

'use strict'

// Requerir el modulo de hapi (Framework)
const Hapi = require('@hapi/hapi')
const handlerbars = require('handlebars') // para implementacion de plantillas
const inert = require('inert') // extiende los metodos disponible en el objeto h
const vision = require('@hapi/vision') //para implementar el uso de vistas. Hay que configurarlo por ser un plugin
const path = require('path') // nos permite definir una ubicación relativa para todos los routes de nuestro proyecto
const routes = require('./routes')

// 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 desde donde va acceder a las rutas. relaviteTo (routes.files)
    routes: {
        files: {
            relativeTo: path.join(__dirname, 'public')
        }
    } 
})

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

  // Arrancar el servidor de HapiJS, se considera una tarea asincrona.
    try {
        // registrando inert
        await server.register(inert)
        //registrando vision
        await server.register(vision)
        //configuracion de vision
        server.views({
            engines: {  //hapi puede usar diferentes engines
                hbs: handlerbars //asociamos el plugin al tipo de archivo
            },
            relativeTo: __dirname, //para que las vistas las busque fuera de /public
            path: 'views', //directorio done colocaremos las vistas dento de nuestro proyecto
            layout: true, //indica que usaremos layouts
            layoutPath: 'views' //ubicacion de layouts
        })
        server.route(routes)
        await server.start()
    } 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)
    }

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

// Inicializar el proyecto
init();
'use strict'

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

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

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

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

init()

👍👌

¡Hola a todos!

Continuando un poco con el primer release que comparti con la inclusión de typescript, les comparto esta implementación con Pug como view engine. Cualquier feedbakc es bienvenida y PR abiertas

release-0,2,view-engine

hapi-repo

import Hapi from '@hapi/hapi';
import inert from '@hapi/inert';
import vision from '@hapi/vision';
import path from 'path';
import pug from 'pug';
import router from '../routes';

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

const init = async () => {
  const server = Hapi.server({ port, host, routes });

  await server.register(inert);
  await server.register(vision);

  server.views({
    engines: { pug },
    relativeTo: path.join(__dirname, '..'),
    path: 'views',
  });

  server.route(router);

  await server.start();
  console.log(`Server online on port: ${server.info.port}`);
};

export { init };


'use strict'

const Hapi = require('hapi')//framework
const handlerbars = require('handlebars')// motor de platillas
const inert =  require('inert')//plugin
const path = require('path')//modulo nativo de Node
const routes = require('./routes')
const vision = require('vision')// plugin para getionar el motor de plantillas

const server = Hapi.server({
    port: 3000,
    host: 'localhost',
    routes: {
        files:{
            //ponemos que para todas las rutas que este sera el directorio de staticos
            relativeTo: path.join(__dirname, 'public')
        }
    }
})

async function init () {
    try {
        //Le debemos indicar a hapi que usaremos este plugin, no basta con requerirlo
        await server.register(inert)
        await server.register(vision)
        server.views({
            // define que tipo de motor de platillas vamos a usar, vision soporta diferentes motores de platillas
            engines:{
                hbs: handlerbars
            },
            relativeTo: __dirname,
            path: 'views',
            layout: true,
            layoutPath: 'views'
        })
        server.route(routes)
        //arrancar el servidor de HapiJS se considera tarea asincrona
        await server.start()
    }
    catch (error) {
        console.error(error);
        process.exit(1)
        //Salir de Node con un codigo de errir (1), 0 es un codigo de exito
    }
    console.log(`Servidor lanzado en: ${server.info.uri}`);
}
//Inicializa el proyecto
init()

Ahora entiendo más el código del proyecto… Gracias MVC