Create an App with NeDB

Nombre: Sergio Lizárraga Pomareda, Miguel Arenas Paz

Docente: Patrick Cuadros Quiroga

Las bases de datos NoSQL son cada vez más populares debido a su flexibilidad, escalabilidad y adecuación para aplicaciones modernas. En este artículo, construiremos una aplicación simple utilizando una base de datos NoSQL la cual sera NeDB y exploraremos los beneficios, usos y los fundamentos de este tipo de bases de datos.

Paso 1: Selección de la Base de Datos NoSQL

Existen diferentes tipos de bases de datos NoSQL:

  • Documentos (Document Stores) que almacenan datos en formato JSON o BSON.

  • Clave-valor (Key-Value) que almacenan datos en pares clave-valor.

  • Columnas Anchas (Wide-Column) que utiliza una arquitectura de columnas flexibles.

  • Grafos (Graph) que son útiles para analizar redes y relaciones complejas.

Para nuestra aplicación, utilizaremos NeDB, una base de datos basada en documentos y escrita en JavaScript, ideal para aplicaciones en tiempo real y prototipos rápidos en Node.js. NeDB almacena datos en formato JSON y tiene la ventaja de ser fácil de implementar y de realizar operaciones CRUD (Crear, Leer, Actualizar y Borrar).

Paso 2: Configuración del Entorno

Asegúrate de tener Node.js instalado en tu máquina. Luego, inicializa un proyecto con npm init y luego usar npm install nedb

Ahora creamos una carpeta con Visual Studio Code la cual tendra la siguiente estructura:

Paso 3: Creación del Servidor en Node.js

En el archivo server.js, crearemos una API REST básica con Node.js y Express para manejar tareas CRUD en NeDB.

const express = require('express');
const NeDB = require('nedb');
const path = require('path');
const app = express();
const port = 3000;


app.use(express.json());
app.use(express.static(path.join(__dirname, '../'))); 


const db = new NeDB({
    filename: 'data/database.db', 
    autoload: true
});


app.get('/', (req, res) => {
    res.sendFile(path.join(__dirname, '../index.html'));
});


app.post('/tasks', (req, res) => {
    const nuevaTarea = req.body;
    db.insert(nuevaTarea, (err, newDoc) => {
        if (err) {
            return res.status(500).send(err);
        }
        res.status(201).send(newDoc);
    });
});

app.get('/tasks', (req, res) => {
    db.find({}, (err, docs) => {
        if (err) {
            return res.status(500).send(err);
        }
        res.send(docs);
    });
});


app.post('/complete/:id', (req, res) => {
    const tareaId = req.params.id;
    db.update({ _id: tareaId }, { $set: { completada: true } }, {}, (err, numAffected) => {
        if (err) {
            return res.status(500).send(err);
        }
        res.sendStatus(200);
    });
});


app.listen(port, () => {
    console.log(`Servidor escuchando en http://localhost:${port}`);
});

Paso 4: Interfaz de Usuario

Nuestra interfaz incluirá un campo para agregar nuevas tareas y una lista que mostrará todas las tareas almacenadas en la base de datos. En el archivo index.html:

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="css/styles.css">
    <title>To-Do List</title>
</head>
<body>
    <h1>Lista de Tareas</h1>
    <input type="text" id="nueva-tarea" placeholder="Nueva tarea">
    <button id="agregar-tarea">Agregar</button>
    <ul id="lista-tareas"></ul>

    <script src="js/app.js"></script>
</body>
</html>

Paso 5: Código de Cliente (JavaScript)

En el archivo app.js, manejaremos la lógica de agregar y completar tareas:

document.addEventListener('DOMContentLoaded', () => {
    const agregarButton = document.getElementById('agregar-tarea');
    const listaTareas = document.getElementById('lista-tareas');
    const nuevaTareaInput = document.getElementById('nueva-tarea');

    agregarButton.addEventListener('click', async () => {
        const tareaTexto = nuevaTareaInput.value;
        if (tareaTexto) {
            const nuevaTarea = { task: tareaTexto, completada: false };

            const response = await fetch('/tasks', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(nuevaTarea)
            });
            const tareaAgregada = await response.json();

            loadTasks();
            nuevaTareaInput.value = '';
        }
    });

    async function loadTasks() {
        const response = await fetch('/tasks');
        const tasks = await response.json();
        const taskList = document.getElementById('lista-tareas');
        taskList.innerHTML = '';

        tasks.forEach(task => {
            const li = document.createElement('li');
            li.textContent = task.task;

            if (task.completada) {
                li.classList.add('completada');
            }

            const completeButton = document.createElement('button');
            completeButton.textContent = 'Completar';
            completeButton.onclick = async () => {
                try {
                    const response = await fetch(`/complete/${task._id}`, { method: 'POST' });
                    if (response.ok) {
                        loadTasks();
                    } else {
                        console.error('Error al completar la tarea:', response.statusText);
                    }
                } catch (error) {
                    console.error('Error al completar la tarea:', error);
                }
            };

            li.appendChild(completeButton);
            taskList.appendChild(li);
        });
    }

    loadTasks();
});

Paso 6: Estilos CSS

Para dar estilo, crea un archivo styles.css y dale una apariencia sencilla:

body {
    font-family: Arial, sans-serif;
}

#lista-tareas {
    list-style-type: none;
}

.completada {
    text-decoration: line-through;
    color: gray;
}

Paso 7: Ejecutar la Aplicación

Para iniciar la aplicación:

  1. Ejecuta el servidor entrando a la terminal de visual studio code(CTRL + Ñ): node server.js

  2. Abre tu navegador y ve a http://localhost:3000

Conclusión

Hemos construido una aplicación básica con una base de datos NoSQL utilizando NeDB y Node.js, explorando los beneficios de las bases de datos NoSQL y cómo son adecuadas para manejar datos flexibles y aplicaciones en tiempo real.