Introducción a Hapi.js
Hapi.js es un marco de trabajo rico y poderoso para construir aplicaciones y servicios web en Node.js. Proporciona un conjunto robusto de características y complementos para simplificar el proceso de desarrollo y facilitar la construcción de aplicaciones escalables y seguras.
Historia
Hapi.js fue creado por Eran Hammer y fue lanzado por primera vez en 2011. Inicialmente fue desarrollado como un proyecto interno en Walmart para manejar su plataforma de comercio electrónico. Más tarde, se convirtió en software de código abierto y ganó popularidad entre la comunidad de Node.js debido a sus características únicas y su capacidad de extensión.
Características
1. Enrutamiento
Hapi.js proporciona un sistema de enrutamiento flexible y declarativo. Le permite definir rutas con diferentes métodos HTTP, parámetros de URL y parámetros de consulta. Aquí tienes un ejemplo:
const Hapi = require('hapi');
const server = Hapi.server({
port: 3000,
host: 'localhost'
});
server.route({
method: 'GET',
path: '/hello/{name}',
handler: (request, h) => {
return `¡Hola, ${request.params.name}!`;
}
});
async function startServer() {
await server.start();
console.log('Servidor en ejecución en:', server.info.uri);
}
startServer();
En el ejemplo anterior, definimos una ruta que escucha las solicitudes GET en la ruta "/hello/{name}". Cuando se realiza una solicitud a esta ruta, el servidor responde con un mensaje de saludo que contiene el parámetro de nombre proporcionado en la URL.
2. Ciclo de vida de la solicitud
Hapi.js proporciona un ciclo de vida detallado de la solicitud, lo que le permite manejar diferentes etapas de una solicitud. Esto incluye la autenticación, validación, preprocesamiento y generación de respuestas. Puede definir complementos y ganchos en diferentes etapas del ciclo de vida de la solicitud para ampliar la funcionalidad. Aquí tienes un ejemplo:
server.ext('onPreHandler', (request, h) => {
console.log('Solicitud recibida:', request.path);
return h.continue;
});
En este ejemplo, utilizamos el método server.ext para definir un gancho de premanejador. Este gancho se ejecuta antes de la función del manejador para cada solicitud entrante. Registramos la ruta de la solicitud y continuamos el ciclo de vida de la solicitud llamando a h.continue.
3. Autenticación y autorización
Hapi.js proporciona soporte incorporado para la autenticación y autorización. Le permite integrar fácilmente diferentes estrategias de autenticación, como basadas en sesiones, basadas en tokens o OAuth. También puede definir reglas de control de acceso para restringir el acceso a rutas o recursos específicos. Aquí tienes un ejemplo:
const Bcrypt = require('bcrypt');
const users = {
john: {
username: 'john',
password: '$2b$10$1Kxv7iXq3c7gjQJ8M6jMduPp2z5mIYF2uNt7Q0mZyWn7pI1n6Xm2e' // 'password'
}
};
const validateUser = async (request, username, password, h) => {
const user = users[username];
if (!user) {
return { credentials: null, isValid: false };
}
const isValid = await Bcrypt.compare(password, user.password);
return { credentials: { id: user.id, name: user.name }, isValid };
};
server.auth.strategy('basic', 'basic', { validate: validateUser });
server.route({
method: 'GET',
path: '/private',
options: {
auth: 'basic'
},
handler: (request, h) => {
return `¡Bienvenido, ${request.auth.credentials.name}!`;
}
});
En este ejemplo, definimos una estrategia de autenticación básica utilizando el método server.auth.strategy. Proporcionamos una función de validación que verifica el nombre de usuario y la contraseña con las credenciales de usuario almacenadas. La función validateUser utiliza Bcrypt para comparar el hash de la contraseña. Luego, aplicamos esta estrategia de autenticación a una ruta estableciendo la opción auth.
4. Complementos y extensibilidad
Hapi.js tiene un rico ecosistema de complementos que se pueden integrar fácilmente en su aplicación. Estos complementos proporcionan características adicionales como registro, almacenamiento en caché, integración de bases de datos y más. También puede crear sus propios complementos para ampliar la funcionalidad de su aplicación. Aquí tienes un ejemplo de cómo usar el complemento hapi-auth-jwt2 para autenticación JWT:
const HapiJwt = require('hapi-auth-jwt2');
await server.register(HapiJwt);
const validateUser = async (decoded, request, h) => {
const user = await User.findById(decoded.id);
if (!user) {
return { isValid: false };
}
return { isValid: true };
};
server.auth.strategy('jwt', 'jwt', {
key: 'tu_clave_secreta',
validate: validateUser
});
server.route({
method: 'GET',
path: '/private',
options: {
auth: 'jwt'
},
handler: (request, h) => {
return `¡Bienvenido, ${request.auth.credentials.name}!`;
}
});
En este ejemplo, registramos el complemento hapi-auth-jwt2 utilizando el método server.register. Luego, definimos una estrategia de autenticación JWT utilizando el método server.auth.strategy. La función validateUser se llama para validar el token JWT decodificado y recuperar el usuario de la base de datos. Finalmente, aplicamos la estrategia de autenticación jwt a una ruta.
Ejemplos
Para obtener más ejemplos y documentación detallada, puedes visitar el sitio web oficial de Hapi.js. El sitio web proporciona guías completas, tutoriales y referencias de API para ayudarte a comenzar con Hapi.js y explorar sus características en profundidad.
En general, Hapi.js es un marco de trabajo potente y versátil para construir aplicaciones y servicios web en Node.js. Su amplio conjunto de características, su sólido ecosistema de complementos y su documentación clara lo convierten en una opción popular entre los desarrolladores.