Bases de datos nosql

6.1. Descripción del proyecto

Vamos a construir una aplicación web con Node.js, Express y Redis.

📌 Flujo de la aplicación:
1️⃣ Un usuario inicia sesión.
2️⃣ Se guarda su sesión en Redis con una expiración de 30 minutos.
3️⃣ Se actualiza un contador de usuarios en línea.
4️⃣ Cuando el usuario se desconecta, su sesión se borra y el contador se actualiza.


6.2. Instalación y configuración

🔹 Requisitos previos:
✔ Tener instalado Node.js
✔ Tener Redis corriendo en el sistema

🔹 Instalar dependencias:
Ejecuta el siguiente comando para instalar los paquetes necesarios:

1npm init -y  # Inicializa el proyecto
2npm install express redis dotenv

Estos paquetes permiten crear un servidor con Express y conectarlo a Redis.

🔹 Iniciar Redis
Si Redis ya está instalado, inícialo con:

1redis-server

Para verificar que funciona, ejecuta:

1redis-cli ping  # Debe responder "PONG"

6.3. Crear el servidor con Express y Redis

📌 Paso 1: Configurar Express y Redis

Crea un archivo server.js y agrega el siguiente código:

1require("dotenv").config();
2const express = require("express");
3const redis = require("redis");
4
5const app = express();
6const PORT = process.env.PORT || 3000;
7
8// Conectar con Redis
9const client = redis.createClient();
10client.connect();
11
12// Manejo de errores en Redis
13client.on("error", (err) => console.error("Error en Redis:", err));
14
15app.use(express.json());
16
17// Variable para contar usuarios en línea
18let usuariosEnLinea = 0;

6.4. Implementar autenticación con Redis

📌 Paso 2: Manejo de sesiones en Redis

Cuando un usuario inicia sesión, guardaremos su sesión en Redis con un tiempo de expiración.

1app.post("/login", async (req, res) => {
2  const { usuario } = req.body;
3  if (!usuario) return res.status(400).send("Usuario requerido");
4
5  // Guardar sesión en Redis con expiración de 30 min
6  await client.setEx(`sesion:${usuario}`, 1800, "activo");
7
8  usuariosEnLinea++;
9  res.send({ mensaje: `Usuario ${usuario} autenticado`, usuariosEnLinea });
10});

📌 Paso 3: Verificar si un usuario está autenticado
Antes de acceder a una página, verificamos si su sesión sigue activa en Redis.

1app.get("/check-session/:usuario", async (req, res) => {
2  const { usuario } = req.params;
3  const sesion = await client.get(`sesion:${usuario}`);
4
5  if (!sesion) {
6    return res.status(401).send("Sesión expirada. Inicia sesión nuevamente.");
7  }
8
9  res.send({ mensaje: `Usuario ${usuario} autenticado` });
10});

📌 Paso 4: Cerrar sesión y actualizar usuarios en línea

Cuando un usuario se desconecta, eliminamos su sesión de Redis y actualizamos el contador.

1app.post("/logout", async (req, res) => {
2  const { usuario } = req.body;
3  if (!usuario) return res.status(400).send("Usuario requerido");
4
5  await client.del(`sesion:${usuario}`);
6
7  usuariosEnLinea = Math.max(0, usuariosEnLinea - 1);
8  res.send({ mensaje: `Usuario ${usuario} desconectado`, usuariosEnLinea });
9});

6.5. Contador de usuarios en línea en tiempo real

📌 Paso 5: Ver cuántos usuarios están en línea

1app.get("/usuarios-en-linea", (req, res) => {
2  res.send({ usuariosEnLinea });
3});

Cada vez que un usuario inicie sesión o cierre sesión, este número se actualizará automáticamente.


6.6. Implementar caché con Redis para acelerar respuestas

📌 Paso 6: Usar Redis para almacenar en caché las respuestas de la API

Imagina que tenemos una API que devuelve datos de productos. En lugar de hacer consultas repetitivas a la base de datos, guardamos la respuesta en Redis durante 60 segundos.

1app.get("/producto/:id", async (req, res) => {
2  const { id } = req.params;
3
4  // Verificar si el producto está en Redis
5  const cacheado = await client.get(`producto:${id}`);
6  if (cacheado) {
7    return res.send({ fuente: "cache", producto: JSON.parse(cacheado) });
8  }
9
10  // Simulación de una consulta a la base de datos
11  const producto = { id, nombre: "Laptop", precio: 1200 };
12
13  // Guardar en Redis con expiración de 60 segundos
14  await client.setEx(`producto:${id}`, 60, JSON.stringify(producto));
15
16  res.send({ fuente: "base de datos", producto });
17});

6.7. Prueba del proyecto

🔹 Ejecutar el servidor
Guarda los cambios y ejecuta el servidor:

1node server.js

🔹 Probar la API con Postman o cURL

1️⃣ Iniciar sesión

1curl -X POST http://localhost:3000/login -H "Content-Type: application/json" -d '{"usuario": "Ana"}'

2️⃣ Verificar sesión

1curl http://localhost:3000/check-session/Ana

3️⃣ Ver usuarios en línea

1curl http://localhost:3000/usuarios-en-linea

4️⃣ Cerrar sesión

1curl -X POST http://localhost:3000/logout -H "Content-Type: application/json" -d '{"usuario": "Ana"}'

5️⃣ Obtener un producto con caché

1curl http://localhost:3000/producto/1

La primera vez vendrá de la base de datos, pero si repites la solicitud en menos de 60 segundos, la respuesta vendrá de Redis (cacheado).