Preparación del entorno
Primero creamos la base de datos y la tabla que usaremos en los ejemplos:
CREATE DATABASE gestion_notas;
USE gestion_notas;
CREATE TABLE notas (
id INT PRIMARY KEY AUTO_INCREMENT,
titulo VARCHAR(255) NOT NULL,
contenido TEXT NOT NULL,
fecha_creacion TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
INSERT INTO notas (titulo, contenido) VALUES
('Primera nota', 'Contenido de ejemplo'),
('Segunda nota', 'Otro contenido');
Método con Pool de conexiones (mysql2)
Esta aproximación utiliza mysql2 con promesas y variables de antorno para la configuración.
Estructura de archivos
proyecto/
├── .env
├── db.js
├── servidor.js
└── package.json
Configuración de variables (.env)
DB_HOST=119.91.31.144
DB_USUARIO=test1
DB_CLAVE=tu_contraseña
DB_NOMBRE=test1
DB_PUERTO=3306
Módulo de conexión (db.js)
import { createPool } from 'mysql2/promise';
import { config } from 'dotenv';
config();
export const conexion = createPool({
host: process.env.DB_HOST,
user: process.env.DB_USUARIO,
password: process.env.DB_CLAVE,
database: process.env.DB_NOMBRE,
port: parseInt(process.env.DB_PUERTO || '3306'),
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
});
Operaciones CRUD (db.js)
export async function obtenerTodas() {
const [filas] = await conexion.execute('SELECT * FROM notas ORDER BY fecha_creacion DESC');
return filas;
}
export async function obtenerPorId(identificador) {
const [resultado] = await conexion.execute(
'SELECT * FROM notas WHERE id = ?',
[identificador]
);
return resultado[0] || null;
}
export async function insertarNota(cabecera, descripcion) {
const [respuesta] = await conexion.execute(
'INSERT INTO notas (titulo, contenido) VALUES (?, ?)',
[cabecera, descripcion]
);
return obtenerPorId(respuesta.insertId);
}
export async function eliminarNota(identificador) {
await conexion.execute('DELETE FROM notas WHERE id = ?', [identificador]);
return { eliminado: true };
}
API Express (servidor.js)
import express from 'express';
import { obtenerTodas, obtenerPorId, insertarNota, eliminarNota } from './db.js';
const aplicacion = express();
aplicacion.use(express.json());
aplicacion.get('/notas', async (peticion, respuesta, siguiente) => {
try {
const datos = await obtenerTodas();
respuesta.json(datos);
} catch (err) {
siguiente(err);
}
});
aplicacion.get('/notas/:identificador', async (peticion, respuesta, siguiente) => {
try {
const elemento = await obtenerPorId(peticion.params.identificador);
if (!elemento) return respuesta.status(404).json({ error: 'No encontrado' });
respuesta.json(elemento);
} catch (err) {
siguiente(err);
}
});
aplicacion.post('/notas', async (peticion, respuesta, siguiente) => {
try {
const { titulo, contenido } = peticion.body;
const creado = await insertarNota(titulo, contenido);
respuesta.status(201).json(creado);
} catch (err) {
siguiente(err);
}
});
aplicacion.delete('/notas/:identificador', async (peticion, respuesta, siguiente) => {
try {
await eliminarNota(peticion.params.identificador);
respuesta.status(204).send();
} catch (err) {
siguiente(err);
}
});
aplicacion.use((error, peticion, respuesta, siguiente) => {
console.error(error);
respuesta.status(500).json({ mensaje: 'Error interno del servidor' });
});
const PUERTO = process.env.PORT || 8080;
aplicacion.listen(PUERTO, () => {
console.log(`Servidor activo en http://localhost:${PUERTO}`);
});
package.json
{
"name": "api-mysql-ejemplo",
"version": "1.0.0",
"type": "module",
"scripts": {
"iniciar": "node servidor.js",
"desarrollo": "nodemon servidor.js"
},
"dependencies": {
"dotenv": "^16.3.0",
"express": "^4.18.0",
"mysql2": "^3.6.0"
},
"devDependencies": {
"nodemon": "^3.0.0"
}
}
Método con conexión simple (mysql)
Alternativa usando el paquete mysql con callbacks, todo en un único archivo:
const express = require('express');
const cors = require('cors');
const mysql = require('mysql');
const aplicacion = express();
aplicacion.use(cors());
aplicacion.use(express.json());
const db = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'gestion_notas'
});
db.connect((err) => {
if (err) {
console.error('Fallo de conexión:', err.message);
return;
}
console.log('Conectado a MySQL, threadId:', db.threadId);
});
aplicacion.get('/api/registros', (req, res) => {
db.query('SELECT id, titulo, contenido, fecha_creacion FROM notas',
(error, resultados) => {
if (error) {
res.status(500).json({ error: error.message });
return;
}
res.json(resultados);
}
);
});
aplicacion.post('/api/registros', (req, res) => {
const { titulo, contenido } = req.body;
db.query(
'INSERT INTO notas (titulo, contenido) VALUES (?, ?)',
[titulo, contenido],
(error, resultado) => {
if (error) {
res.status(500).json({ error: error.message });
return;
}
res.status(201).json({ id: resultado.insertId, titulo, contenido });
}
);
});
const PUERTO = process.env.PORT || 3000;
aplicacion.listen(PUERTO, () => {
console.log(`Escuchando en puerto ${PUERTO}`);
});
Diferencias clave entre enfoques
| Característica | mysql2 con Pool | mysql con conexión única |
|---|---|---|
| Manejo de async/await | Nativo con promesas | Requiere wrapper o callbacks |
| Randimiento concurrente | Superior (reutiliza conexiones) | Limitado a una conexión |
| Sintaxis de imports | ES Modules | CommonJS |
| Ideal para | Producción y APIs REST | Prototipos rápidos |
Instalación de dependencias
# Para el primer método (mysql2)
npm install mysql2 dotenv express
# Para el segundo método (mysql)
npm install mysql express cors
# Ejecución
node servidor.js
# o con nodemon
npx nodemon servidor.js