Tutorial Completo para Crear una API RESTful con Express.js y MongoDB en Node.js
En este tutorial aprenderás, paso a paso, cómo crear una API RESTful utilizando Express.js y MongoDB en Node.js. Está dirigido a desarrolladores principiantes e intermedios interesados en el desarrollo backend con JavaScript. Cubriremos desde la configuración inicial, conexión a la base de datos, definición de esquemas con Mongoose, hasta la implementación de rutas CRUD, manejo de errores y pruebas básicas con Postman.
¡Vamos a programar!
Índice
- Configuración del entorno
- Conexión a MongoDB con Mongoose
- Definición de esquemas con Mongoose
- Implementación de rutas CRUD en Express.js
- Manejo de errores y buenas prácticas
- Pruebas básicas con Postman
- Conclusión y próximos pasos
Configuración del entorno
Primero, necesitamos preparar nuestro ambiente para el desarrollo.
Requisitos previos
- Node.js instalado (preferiblemente la versión LTS).
- MongoDB instalado localmente o una cuenta en MongoDB Atlas.
- Editor de código (e.g. Visual Studio Code).
- Postman instalado para probar la API.
Creando el proyecto
- Crea una carpeta para tu proyecto y navega a ella:
1 2 3 |
mkdir tutorial-express-mongodb cd tutorial-express-mongodb |
- Inicializa un proyecto Node.js:
1 2 |
npm init -y |
- Instala las dependencias principales:
1 2 |
npm install express mongoose dotenv |
express
para crear el servidor API.mongoose
para interactuar con MongoDB.dotenv
para manejar variables de entorno.
- (Opcional) Instala nodemon para reinicio automático durante el desarrollo:
1 2 |
npm install --save-dev nodemon |
Agrega en package.json
un script para ejecutar con nodemon:
1 2 3 4 5 |
"scripts": { "start": "node index.js", "dev": "nodemon index.js" } |
¡Ya tenemos nuestro entorno listo!
Conexión a MongoDB con Mongoose
Es importante conectar nuestra aplicación a la base de datos.
Crear archivo .env
En la raíz crea un archivo .env
para almacenar la cadena de conexión:
1 2 3 |
MONGODB_URI=mongodb://localhost:27017/tutorialdb PORT=3000 |
Si usas MongoDB Atlas pega la URI proporcionada allí.
Configura la conexión
Crea el archivo index.js
y agrega:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
require('dotenv').config(); // Carga variables de entorno const express = require('express'); const mongoose = require('mongoose'); const app = express(); const port = process.env.PORT || 3000; // Middleware para parsear JSON app.use(express.json()); // Conexión a MongoDB mongoose.connect(process.env.MONGODB_URI, { useNewUrlParser: true, useUnifiedTopology: true }) .then(() => console.log('Conectado a MongoDB')) .catch(err => { console.error('Error conectando a MongoDB:', err); process.exit(1); // Detener app en error crítico }); // Ruta base para verificar server app.get('/', (req, res) => { res.send('API RESTful con Express.js y MongoDB está corriendo'); }); app.listen(port, () => { console.log(`Servidor escuchando en puerto ${port}`); }); |
Para probar que funciona, ejecuta:
1 2 |
npm run dev |
y abre http://localhost:3000
en tu navegador o Postman.
Definición de esquemas con Mongoose
Con MongoDB no se requiere esquema, pero con Mongoose definimos estructuras para uniformidad.
Crear un esquema para un recurso ejemplo: Tarea
Vamos a crear una colección de “tareas” para una to-do list.
Crea una carpeta models
y dentro Task.js
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
const mongoose = require('mongoose'); const taskSchema = new mongoose.Schema({ title: { type: String, required: true, trim: true }, description: { type: String, trim: true }, completed: { type: Boolean, default: false }, createdAt: { type: Date, default: Date.now } }); module.exports = mongoose.model('Task', taskSchema); |
Explicación:
title
: título obligatorio y sin espacios innecesarios.description
: opcional.completed
: estado de la tarea, por defecto falso.createdAt
: fecha auto asignada.
Implementación de rutas CRUD en Express.js
Vamos a permitir crear, obtener, actualizar y eliminar tareas.
Crear una carpeta routes
y un archivo tasks.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
const express = require('express'); const router = express.Router(); const Task = require('../models/Task'); // Crear una nueva tarea router.post('/', async (req, res) => { try { const task = new Task(req.body); const savedTask = await task.save(); res.status(201).json(savedTask); } catch (error) { res.status(400).json({ message: error.message }); } }); // Obtener todas las tareas router.get('/', async (req, res) => { try { const tasks = await Task.find(); res.json(tasks); } catch (error) { res.status(500).json({ message: error.message }); } }); // Obtener una tarea por ID router.get('/:id', async (req, res) => { try { const task = await Task.findById(req.params.id); if (!task) return res.status(404).json({ message: 'Tarea no encontrada' }); res.json(task); } catch (error) { res.status(500).json({ message: error.message }); } }); // Actualizar tarea por ID router.put('/:id', async (req, res) => { try { const updatedTask = await Task.findByIdAndUpdate(req.params.id, req.body, { new: true, runValidators: true }); if (!updatedTask) return res.status(404).json({ message: 'Tarea no encontrada' }); res.json(updatedTask); } catch (error) { res.status(400).json({ message: error.message }); } }); // Eliminar tarea por ID router.delete('/:id', async (req, res) => { try { const deletedTask = await Task.findByIdAndDelete(req.params.id); if (!deletedTask) return res.status(404).json({ message: 'Tarea no encontrada' }); res.json({ message: 'Tarea eliminada' }); } catch (error) { res.status(500).json({ message: error.message }); } }); module.exports = router; |
Integra las rutas en index.js
1 2 3 4 5 |
const tasksRouter = require('./routes/tasks'); // Dar prefijo /api/tasks a las rutas app.use('/api/tasks', tasksRouter); |
Ahora tendrás un API para gestionar tareas con:
| Método | URL | Función |
|——–|——————-|——————-|
| POST | /api/tasks | Crear tarea |
| GET | /api/tasks | Listar tareas |
| GET | /api/tasks/:id | Obtener tarea |
| PUT | /api/tasks/:id | Actualizar tarea |
| DELETE | /api/tasks/:id | Eliminar tarea |
Manejo de errores y buenas prácticas
Un buen backend debe manejar errores correctamente y mantener código limpio.
Buenas prácticas recomendadas:
- Usa
try/catch
en funciones async para capturar errores. - Devuelve códigos HTTP adecuados (201 para creación, 404 para no encontrado, etc).
- Valida los datos recibidos (Mongoose ayuda con eso).
- No expongas errores internos exactos al cliente; da mensajes claros y seguros.
- Usa variables de entorno para datos sensibles (como la URI de MongoDB).
- Organiza el proyecto en carpetas claras (
models
,routes
,controllers
si creas separación).
Ejemplo de middleware para manejo global de errores (opcional):
1 2 3 4 5 6 7 8 9 10 11 |
// Middleware para manejar rutas no encontradas app.use((req, res, next) => { res.status(404).json({ message: 'Ruta no encontrada' }); }); // Middleware global de errores app.use((err, req, res, next) => { console.error(err.stack); res.status(500).json({ message: 'Error interno del servidor' }); }); |
Puedes agregarlo al final de tus configuraciones en index.js
.
Pruebas básicas con Postman
Postman es una herramienta ideal para probar nuestra API RESTful.
Cómo probar:
- Crear tarea (POST)
- URL:
http://localhost:3000/api/tasks
- Body (raw JSON):
json
{
"title": "Aprender Express",
"description": "Seguir tutorial paso a paso"
}
- Enviar y verificar que se cree correctamente (código 201).
- Listar tareas (GET)
- URL:
http://localhost:3000/api/tasks
- Debe mostrar un array con las tareas.
- Obtener tarea por ID (GET)
- URL:
http://localhost:3000/api/tasks/{id}
- Reemplaza
{id}
con el ID de alguna tarea creada.
- Actualizar tarea (PUT)
- URL:
http://localhost:3000/api/tasks/{id}
- Body (raw JSON):
json
{
"completed": true
}
- Verifica que la tarea se actualice.
- Eliminar tarea (DELETE)
- URL:
http://localhost:3000/api/tasks/{id}
- Debe responder con mensaje de tarea eliminada.
Conclusión y próximos pasos
¡Felicidades! Has construido una API RESTful básica pero funcional usando Express.js y MongoDB en Node.js.
Resumen
- Configuraste tu entorno con Node, Express, Mongoose y dotenv.
- Conectaste tu app a MongoDB con Mongoose.
- Definiste esquemas para tus datos usando modelos.
- Implementaste rutas CRUD con manejo de errores.
- Probaste la API usando Postman.
Qué puedes hacer después
- Añadir autenticación con JWT para proteger rutas.
- Usar validaciones más robustas (e.g., con
joi
oexpress-validator
). - Implementar paginación y filtros en endpoints.
- Modulariza tu código separando controladores y servicios.
- Desplegar tu API en un servidor (Heroku, Vercel, etc).
Si te gustó este tutorial Express.js y quieres aprender más sobre desarrollo backend y programación JavaScript, ¡síguenos para más contenido y comparte este artículo con tus colegas!
Buenas prácticas para desarrollo backend con JavaScript
- Mantén tu código limpio y modular.
- Documenta tu API, considera usar Swagger.
- Versiona tu API para evitar rupturas en clientes.
- Maneja correctamente las variables sensibles.
- Realiza pruebas unitarias e integradas.
- Optimiza consultas a la base de datos para rendimiento.
Gracias por leer, ¡manos a la obra y feliz programación!