
Guía Práctica: API REST con Express.js y NeDB

Angela Sofía Osorio
Tiempo de lectura 2 minutes
Contents
Guía Práctica: API REST con Express.js y NeDB
1. Configuración Inicial
import express from 'express';
import NeDB from 'nedb';
import util from 'util';
const PORT = import.meta?.env?.PORT || 3000; // Puerto desde variables de entorno o 3000
JavaScript- Módulos clave:
express
: Framework para crear el servidor web.nedb
: Base de datos NoSQL embebida (similar a MongoDB).util
: Para convertir callbacks en Promesas.
2. Inicializar Express
const app = express();
app.use(express.json()); // Middleware para parsear JSON
JavaScript- Middleware esencial:
- Sin
express.json()
, las peticiones POST/PUT no podrán leer el cuerpo en formato JSON.
3. Configuración Detallada de NeDB
Paso 1: Extender la clase NeDB
export class LocalDB extends NeDB {
constructor(options) {
super(options); // Hereda constructor de NeDB
// Promisificación de métodos
this.removeAsync = util.promisify(this.remove.bind(this));
this.insertAsync = util.promisify(this.insert.bind(this));
this.updateAsync = util.promisify(this.update.bind(this));
this.findAsync = util.promisify(this.find.bind(this));
this.findOneAsync = util.promisify(this.findOne.bind(this));
}
}
JavaScript- ¿Por qué
bind(this)
? - Mantiene el contexto de la instancia al ejecutar métodos.
- Sin esto, obtendrías errores como
Cannot read property 'exec' of undefined
. - Métodos promisificados:
- Permiten usar
async/await
en lugar de callbacks. Ejemplo:javascript await SURVERY_DB.insertAsync({ key: 'value' }); // Operación bloqueante
Paso 2: Crear Instancia de la Base de Datos
export const SURVERY_DB = new LocalDB({
filename: './src/database/survery.db', // Archivo físico de datos
autoload: true // Carga automática al iniciar
});
JavaScript- Parámetros clave:
filename
: Ruta del archivo de almacenamiento (creado automáticamente si no existe).autoload: true
: Carga los datos al instanciar la base.- Estructura de documentos:
- Cada documento tiene un
_id
único de 16 caracteres (ej:hT4sLm9Pq6R2vX7z
). - Almacenamiento en disco: Persistente entre reinicios del servidor.
4. Endpoints CRUD
POST /options – Crear Documento
app.post('/options', async ({ body }, res) => {
const { key, ...rest } = body;
if (!key) return res.status(401).send(); // Validación simple
try {
const result = await SURVERY_DB.insertAsync(rest); // Insertar sin key
res.json(result);
} catch (error) {
res.status(500).send('Error interno');
}
});
JavaScript- Validación mínima: Campo
key
obligatorio. - Uso típico:
curl -X POST http://localhost:3000/options -H "Content-Type: application/json" -d '{"key": "secret", "name": "Ejemplo"}'
JavaScriptGET /option/:id – Obtener Documento por ID
app.get('/option/:id', async ({ params }, res) => {
const { id } = params;
if (!/^\w{16}$/.test(id)) return res.status(400).send(); // Validación con regex
try {
const { _id, ...result } = await SURVERY_DB.findOneAsync({ _id: id });
res.json(result); // Excluye _id en la respuesta
} catch {
res.status(404).send();
}
});
JavaScript- Regex
/^\w{16}$/
: Asegura que el ID tenga 16 caracteres alfanuméricos.
GET /options – Listar Todos los Documentos
app.get('/options', async (_, res) => {
try {
const result = await SURVERY_DB.findAsync({}); // Consulta vacía = todos los documentos
res.json(result);
} catch {
res.status(404).send();
}
});
JavaScript5. Manejo de Errores
- Códigos HTTP claros:
400
: ID mal formateado.401
: Falta campo obligatorio.404
: Documento no existe.500
: Error interno del servidor.- Buenas prácticas:
- En producción, evita enviar detalles de errores internos al cliente.
- Usa logs para diagnóstico:
console.error(error)
.
6. Iniciar el Servidor
app.listen(PORT, () => {
console.log(`\x1b[33mServidor activo en http://localhost:${PORT}/\x1b[39m`);
});
JavaScript- ANSI escape codes:
\x1b[33m
(amarillo) y\x1b[39m
(reset color).
Recap
Este setup ofrece una API funcional con:
- Persistencia de datos (NeDB).
- Validaciones básicas (regex, campos obligatorios).
- Manejo moderno de async/await.