0% encontró este documento útil (0 votos)
5 vistas16 páginas

Apunte Node Express SQL NoSQL API Completo

Este documento es una guía completa sobre el uso de Node.js, Express, SQL, NoSQL y la creación de APIs RESTful con autenticación JWT, incluyendo explicaciones detalladas de cada bloque de código. Cubre desde la instalación y configuración de Node.js, hasta la conexión con bases de datos y la implementación de buenas prácticas de seguridad. También incluye ejemplos prácticos y comandos útiles para facilitar el desarrollo.

Cargado por

giulianoortego
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
5 vistas16 páginas

Apunte Node Express SQL NoSQL API Completo

Este documento es una guía completa sobre el uso de Node.js, Express, SQL, NoSQL y la creación de APIs RESTful con autenticación JWT, incluyendo explicaciones detalladas de cada bloque de código. Cubre desde la instalación y configuración de Node.js, hasta la conexión con bases de datos y la implementación de buenas prácticas de seguridad. También incluye ejemplos prácticos y comandos útiles para facilitar el desarrollo.

Cargado por

giulianoortego
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd

Apunte Completo: Node.

js, Express, SQL, NoSQL y API


RESTful (con JWT)
Guía paso a paso con explicaciones línea por línea

Autor: Giuliano Federico Ortego


Resumen:
Este apunte cubre desde los fundamentos de [Link], el uso de Express para crear
servidores y APIs, la conexión y uso de bases de datos SQL (MySQL) y NoSQL (MongoDB),
hasta la construcción de una API RESTful completa con autenticación JWT. Cada bloque de
código incluye explicación detallada línea por línea.
Índice
1. 1. Introducción a [Link]
2. 2. Módulos y sistema de paquetes (npm)
3. 3. Asincronía en [Link]: callbacks, promesas y async/await
4. 4. Express: servidor básico y middleware
5. 5. Manejo de rutas, routers y controladores
6. 6. Conexión a MySQL (SQL) — pool y consultas seguras
7. 7. Conexión a MongoDB (NoSQL) con Mongoose
8. 8. APIs RESTful: principios y ejemplos
9. 9. Autenticación con JWT — registro, login y middleware
10.10. Ejemplo completo: Express + MySQL (estructura, código y explicación)
11.11. Buenas prácticas y seguridad
12.12. Comandos útiles, pruebas con Postman/cURL y anexos
1. Introducción a [Link]
[Link] es un entorno de ejecución para JavaScript que permite ejecutar código JavaScript
fuera del navegador. Está basado en el motor V8 de Chrome y usa un modelo de I/O
orientado a eventos y no bloqueante, ideal para aplicaciones escalables I/O-intensivas.
Instalación y verificaciones básicas:
1) Descargar instalador desde [Link]
2) Verificar versiones:
node -v # muestra versión de node
npm -v # muestra versión del gestor de paquetes npm
3) Inicializar proyecto:
npm init -y # crea [Link] con valores por defecto

1.1 Ejemplo: Hola Mundo en [Link] (archivo [Link])


// 1. Muestra un mensaje en la consola del sistema
[Link]("Hola Mundo desde [Link]");
Explicación línea por línea:
• [Link](...) — Función nativa de JavaScript que imprime texto en la consola. En
[Link] esta salida aparece en la terminal donde ejecutás 'node [Link]'.
Ejecutar: node [Link]
2. Módulos y sistema de paquetes (npm)
Node usa CommonJS (require/exports) por defecto en versiones tradicionales y ES Modules
(import/export) si se habilita con 'type':'module' en [Link] o archivo .mjs. npm
permite instalar librerías y guardar dependencias en [Link].
Ejemplo CommonJS:
const fs = require('fs');
const datos = [Link]('[Link]','utf8');

Ejemplo ES Module:
import fs from 'fs';
const datos = await [Link]('[Link]','utf8');
Explicación: require('modulo') importa el módulo y devuelve su API. import ... from ... es la
sintaxis moderna y puede requerir configuración en [Link].
3. Asincronía en [Link]: callbacks, promesas y async/await
[Link] es asíncrono: muchas operaciones (I/O, red, disco) no bloquean el hilo principal.
Existen varias formas de manejarlo:
- Callbacks (estilo antiguo)
// Callback example (no recomendable para cadenas largas — 'callback hell')
const fs = require('fs');
[Link]('[Link]', 'utf8', function(err, data)
{ if (err) { [Link](err); return; }
[Link](data);
});
Explicación: readFile recibe una función callback con (err, data). Si hay error, err será distinto de
null.
- Promesas
// Promises example
const fs = require('fs').promises;
[Link]('[Link]', 'utf8')
.then(data => [Link](data))
.catch(err => [Link](err));
- async / await
// Async/Await (más limpio)
const fs = require('fs').promises;
async function leer() {
try {
const data = await [Link]('[Link]', 'utf8');
[Link](data);
} catch (err) {
[Link](err);
}
}
leer();
Explicación: async marca la función como asíncrona; await pausa la ejecución dentro de
esta función hasta que la promesa se resuelva o rechace.
4. Express — Servidor básico y middleware
Express es un framework minimalista para crear servidores HTTP y APIs. Instalación:
npm install express
Ejemplo básico ([Link]):
// 1) Importa Express
const express = require('express');
// 2) Crea la app
const app = express();
// 3) Middleware para parsear JSON
[Link]([Link]());
// 4) Ruta GET raíz
[Link]('/', (req, res) => {
// req: objeto petición, res: objeto respuesta
[Link]('Hola desde Express');
});
// 5) Inicia servidor en puerto 3000
const PORT = 3000;
[Link](PORT, () => [Link](`Servidor corriendo en [Link]
Explicación línea por línea:
•const express = require('express'); — importa la librería Express instalada con npm.
•const app = express(); — instancia principal de la aplicación donde registrás rutas y middleware.
•[Link]([Link]()); — middleware que transforma automáticamente JSON del body en
[Link].
•[Link]('/', (req, res) => {...}); — define ruta GET en '/'. req es la petición, res la respuesta.
•[Link](PORT, ...) — pone a escuchar el servidor en un puerto.
5. Manejo de rutas, routers y controladores
Para mantener el código organizado conviene separar rutas (routes), lógica (controllers) y
acceso a datos (models). Ejemplo de router para productos:
// routes/[Link]
const express = require('express');
const router = [Link]();
const productosController = require('../controllers/[Link]');

[Link]('/', [Link]);
[Link]('/', [Link]);
[Link] = router;

// controllers/[Link]
[Link] = async (req, res, next) => {
// lógica para obtener productos
[Link]([]);
};
[Link] = async (req, res, next) => {
// lógica para crear producto
[Link](201).json({ id: 1 });
};
Explicación: router agrupa rutas relacionadas y se monta en la app principal con
[Link]('/productos', router). Los controladores contienen la lógica (consultas,
validaciones).
6. Conexión a MySQL (SQL) — pool y consultas seguras
Instalar driver mysql2:
npm install mysql2
Crear un pool de conexiones ([Link]):
// [Link]
const mysql = require('mysql2/promise'); // usamos la variante promise
const pool = [Link]({
host: 'localhost',
user: 'root',
password: '',
database: 'tienda',
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
});
[Link] = pool;
Explicación: createPool gestiona múltiples conexiones y mejora rendimiento en
aplicaciones concurrentes. Usamos la versión promise para usar async/await.
Ejemplo: CRUD básico (controller) usando consultas parametrizadas para evitar inyección SQL:
// controllers/[Link] (MySQL)
const pool = require('../db');
[Link] = async (req, res, next) => {
const [rows] = await [Link]('SELECT id, nombre, precio FROM productos');
[Link](rows);
};
[Link] = async (req, res, next) =>
{ const { nombre, precio } = [Link];
const [result] = await [Link]('INSERT INTO productos (nombre, precio) VALUES (?, ?)', [nombre,
[Link](201).json({ id: [Link], nombre, precio });
};
Explicación clave:
• [Link](sql, params) — params reemplazan '?' en la consulta; evita concatenar
strings y protege contra inyección SQL.
•[Link] — id generado por la base de datos tras el
INSERT. SQL para crear tabla de ejemplo:
CREATE DATABASE IF NOT EXISTS tienda;
USE tienda;
CREATE TABLE IF NOT EXISTS productos
( id INT AUTO_INCREMENT PRIMARY KEY,
nombre VARCHAR(100) NOT NULL,
precio DECIMAL(10,2) NOT NULL,
creado_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
7. Conexión a MongoDB (NoSQL) con Mongoose
Instalar mongoose:
npm install mongoose
Código de conexión (db_mongo.js):
// db_mongo.js
const mongoose = require('mongoose');
[Link]('mongodb://localhost:27017/tienda', { useNewUrlParser: true, useUnifiedTopology: true
.then(() => [Link]('Conectado a MongoDB'))
.catch(err => [Link]('Error de conexión:', err));
[Link] = mongoose;
Ejemplo de esquema y modelo (models/[Link]):
const { Schema, model } = require('mongoose');
const ProductoSchema = new Schema({
nombre: { type: String, required: true },
precio: { type: Number, required: true },
creadoAt: { type: Date, default: [Link] }
});
[Link] = model('Producto', ProductoSchema);
Operaciones básicas (controller):
// controllers/[Link] (MongoDB)
const Producto = require('../models/[Link]');
[Link] = async (req, res, next) => {
const productos = await [Link]();
[Link](productos);
};
[Link] = async (req, res, next) => {
const nuevo = new Producto([Link]);
await [Link]();
[Link](201).json(nuevo);
};
Diferencias clave SQL vs NoSQL:
- SQL: esquemas rígidos, relaciones, ACID (según motor), consultas estructuradas con JOINs.
- NoSQL (MongoDB): documentos JSON flexibles, fácil evolución de esquemas,
replicación y particionado (sharding). Ideal para datos semi-estructurados.
8. API RESTful: principios y ejemplos
Principios REST básicos:
- Recursos identificables por URIs (ej: /productos).
- Uso de verbos HTTP: GET, POST, PUT/PATCH, DELETE.
- Stateless: cada petición contiene la información necesaria para procesarla (ej: token en headers).
- Códigos de estado HTTP apropiados: 200, 201, 400, 401, 403,
404, 500. Ejemplo de endpoints para recurso 'productos':
GET /productos # listar
GET /productos/:id # obtener uno
POST /productos # crear
PUT /productos/:id # actualizar todo
PATCH /productos/:id # actualizar parcialmente
DELETE /productos/:id # eliminar
Manejo de errores: crear middleware de error para centralizar respuestas y logging.
// middleware/[Link] [Link]
= (err, req, res, next) => {
[Link](err);
[Link]([Link] || 500).json({ error: [Link] || 'Error interno' });
};
9. Autenticación con JWT (JSON Web Tokens)
Instalar dependencias:
npm install jsonwebtoken bcryptjs
Flujo general:
1) Registro: guardar usuario con password hasheada. 2) Login: validar password y emitir
JWT firmado con secreto. 3) Rutas protegidas: middleware verifica token y adjunta
información del usuario a req. Ejemplo completo (usando MySQL para usuarios):
// controllers/[Link] (ejemplo con bcrypt y jwt)
const pool = require('../db');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const JWT_SECRET = [Link].JWT_SECRET || 'CAMBIAR_POR_SECRETO';

[Link] = async (req, res, next) =>


{ const { username, password } = [Link];
const passwordHash = await [Link](password, 10); // 1) hashear contraseña
const [result] = await [Link]('INSERT INTO usuarios (username, password_hash) VALUES (?, ?)',
[Link](201).json({ id: [Link], username });
};

[Link] = async (req, res, next) =>


{ const { username, password } = [Link];
const [rows] = await [Link]('SELECT id, password_hash FROM usuarios WHERE username = ?', [userna
if ([Link] === 0) return [Link](401).json({ message: 'Usuario no encontrado' });
const user = rows[0];
const valid = await [Link](password, user.password_hash); // 2) comparar
if (!valid) return [Link](401).json({ message: 'Credenciales inválidas' });
// 3) generar token
const token = [Link]({ id: [Link], username }, JWT_SECRET, { expiresIn: '1h' });
[Link]({ token });
};
Middleware para verificar token:
// middleware/[Link]
const jwt = require('jsonwebtoken');
const JWT_SECRET = [Link].JWT_SECRET || 'CAMBIAR_POR_SECRETO';
[Link] = (req, res, next) => {
const authHeader = [Link];
if (!authHeader) return [Link](401).json({ message: 'Token requerido' });
// header formato: 'Bearer <token>'
const token = [Link](' ')[1];
try {
const decoded = [Link](token, JWT_SECRET);
[Link] = decoded; // pasa el payload del token
next();
} catch (err) {
return [Link](401).json({ message: 'Token inválido' });
}
};
Explicación clave:
• [Link](password, saltRounds) — genera hash de contraseña; nunca guardar
contraseñas en texto claro. • [Link](payload, secret, options) — firma el token; el secret
debe ser largo y guardado en variables de entorno. • [Link] — valida firma y
expiración.
10. Ejemplo completo: Express + MySQL (estructura y código)
Estructura de proyecto recomendada:
/src
/controllers
[Link]
[Link]
/routes
[Link]
[Link]
/models
(si usás ORM, aquí van los modelos)
/middlewares
[Link]
[Link]
[Link] [Link]
[Link]
[Link]
[Link] (archivo principal) — explicado:
// [Link]
require('dotenv').config(); // 1) carga variables de entorno desde .env
const express = require('express'); // 2) import express
const app = express(); // 3) crea app
[Link]([Link]()); // 4) para parsear JSON
const productosRouter = require('./routes/[Link]');
const authRouter = require('./routes/[Link]');
[Link]('/api/productos', productosRouter); // 5) monta router de productos
[Link]('/api/auth', authRouter); // 6) monta router de auth
const errorHandler = require('./middlewares/errorHandler');
[Link](errorHandler); // 7) middleware de errores al final
const PORT = [Link] || 3000;
[Link](PORT, () => [Link](`Server en puerto ${PORT}`));
Explicación línea por línea:
• require('dotenv').config() — carga variables de entorno desde un archivo .env (por
ejemplo DB credentials, JWT_SECRET).
• [Link]('/api/productos', productosRouter) — todas las rutas definidas en
productosRouter estarán prefijadas por /api/productos.
11. Buenas prácticas y seguridad
•Usar variables de entorno (dotenv) para claves y credenciales; NUNCA subir .env a github.
•Validar y sanitizar toda entrada de usuario (express-validator, Joi).
•Usar consultas parametrizadas/prepared statements para SQL.
•Manejar errores centralizadamente y no exponer trazas en producción.
•Usar HTTPS en producción y forzar HSTS si corresponde.
•Configurar CORS adecuadamente. No habilitar * en producción sin analizar riesgos.
•Aplicar rate limiting (express-rate-limit) para mitigar brute force y DDOS básicos.
•Usar helmet para configurar cabeceras de seguridad HTTP.
•Guardar tokens y secretos en almacenes seguros (Vault, AWS Secrets Manager) si es posible.
•Logs estructurados (winston/pino) y monitoreo (Prometheus, Grafana, Sentry).
•Realizar pruebas: unitarias (Jest, Mocha), integración y pruebas end-to-end.
•Documentar APIs con OpenAPI/Swagger y mantener documentación actualizada.
•Versionar la API (ej: /api/v1/) para cambios breaking.
•Usar migrations para cambios en esquema (Flyway, Sequelize CLI, Knex migrations).
•Implementar backup y políticas de recuperación para bases de datos.
12. Comandos útiles, pruebas con Postman / cURL y anexos
Ejemplos cURL:
# Crear producto (POST JSON)
curl -X POST [Link] -H "Content-Type: application/json" -d '{"nombre":"Co

# Login (obtener token)


curl -X POST [Link] -H "Content-Type: application/json" -d '{"username":

# Acceder a ruta protegida con token


curl -H "Authorization: Bearer <TOKEN>" [Link]
Archivo .env recomendado (ejemplo):
# .env
PORT=3000
DB_HOST=localhost
DB_USER=root
DB_PASS=
DB_NAME=tienda
JWT_SECRET=CAMBIAR_POR_SECRETO_LARGO
SQL para crear tabla de usuarios (MySQL):
CREATE TABLE IF NOT EXISTS usuarios
( id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(100) NOT NULL UNIQUE,
password_hash VARCHAR(255) NOT NULL, creado_at
TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Anexo: checklist rápido para desplegar en producción


•Configurar variables de entorno en el servidor (no usar .env en repo).
•Habilitar HTTPS con certificado válido.
•Configurar backups de base de datos.
•Configurar procesos (PM2, systemd) para mantener app arriba.
•Configurar logs y rotación de logs.
•Revisar dependencias y actualizar vulnerabilidades (npm audit).
Fin del apunte — Giuliano Ortego
Generado: 07 de August de 2025

También podría gustarte