api-node-solid-mongo-manual
v1.0.0
Published
API sencilla con Node.js, Express, MongoDB en Docker, arquitectura SOLID y librería local
Maintainers
Readme
Manual de prácticas: API Node.js + MongoDB Docker + Librería local
1. Datos generales
Práctica: Implementación de una API sencilla con Node.js, Express, MongoDB en Docker, arquitectura SOLID, 3 middlewares y una librería local reutilizable.
Objetivo: Crear una API funcional para productos, conectada a una base de datos MongoDB ejecutada con Docker, aplicando separación por capas y reutilización de código mediante una librería propia.
2. Tecnologías utilizadas
- Node.js
- Express
- MongoDB
- Docker
- Docker Compose
- Mongoose
- dotenv
- cors
- Insomnia
- Librería local npm:
product-inventory-utils
3. Estructura del proyecto
api-node-solid-mongo-manual/
│
├── docker-compose.yml
├── package.json
├── .env
├── README.md
│
├── packages/
│ └── product-inventory-utils/
│ ├── package.json
│ ├── README.md
│ ├── test.js
│ └── src/
│ └── index.js
│
└── src/
├── app.js
├── server.js
│
├── config/
│ └── env.js
│
├── controllers/
│ └── product.controller.js
│
├── database/
│ └── mongo.connection.js
│
├── middlewares/
│ ├── auth.middleware.js
│ ├── logger.middleware.js
│ └── validateProduct.middleware.js
│
├── models/
│ └── product.model.js
│
├── repositories/
│ └── product.repository.js
│
├── routes/
│ └── product.routes.js
│
└── services/
└── product.service.js4. Explicación de arquitectura SOLID
El proyecto está separado en capas para que cada parte tenga una responsabilidad específica.
| Carpeta | Función |
|---|---|
| routes | Define las rutas o endpoints de la API |
| controllers | Recibe la petición y devuelve la respuesta |
| services | Contiene la lógica de negocio |
| repositories | Se comunica con la base de datos |
| models | Define la estructura de los datos en MongoDB |
| middlewares | Intercepta peticiones para validar, autenticar o registrar logs |
| database | Contiene la conexión a MongoDB |
| packages | Contiene la librería local npm |
5. Middlewares implementados
5.1 Logger middleware
Archivo:
src/middlewares/logger.middleware.jsFunción: muestra en consola cada petición realizada.
Ejemplo:
[GET] /api/products
[POST] /api/products5.2 Auth middleware
Archivo:
src/middlewares/auth.middleware.jsFunción: protege endpoints que modifican datos usando una API Key.
Header requerido:
x-api-key: 123455.3 Validate product middleware
Archivo:
src/middlewares/validateProduct.middleware.jsFunción: valida que el producto tenga datos correctos antes de guardarlo.
6. Librería local implementada
La librería se llama:
product-inventory-utilsEstá ubicada en:
packages/product-inventory-utilsFunciones de la librería
| Función | Qué hace |
|---|---|
| validateProduct(product) | Valida que el producto tenga name, price y stock correctos |
| formatProductName(name) | Quita espacios y convierte el nombre a mayúsculas |
| calculateInventoryValue(price, stock) | Calcula el valor total del inventario |
| hasStock(stock) | Indica si hay stock disponible |
| applyDiscount(price, discount) | Aplica un descuento al precio |
Ejemplo de uso de la librería
const {
validateProduct,
formatProductName,
calculateInventoryValue,
hasStock,
applyDiscount
} = require("product-inventory-utils");
const product = {
name: " arroz ",
price: 32,
stock: 15
};
console.log(validateProduct(product));
console.log(formatProductName(product.name));
console.log(calculateInventoryValue(product.price, product.stock));
console.log(hasStock(product.stock));
console.log(applyDiscount(product.price, 10));7. Requisitos antes de ejecutar
Debes tener instalado:
- Node.js
- npm
- Docker
- Docker Compose
- Insomnia
Verifica versiones:
node -v
npm -v
docker --version
docker compose version8. Paso a paso para ejecutar el proyecto
Paso 1: Entrar a la carpeta del proyecto
cd api-node-solid-mongo-manualPaso 2: Instalar dependencias
npm installEste comando instala Express, Mongoose y también la librería local:
product-inventory-utilsPaso 3: Levantar MongoDB con Docker
docker compose up -dVerifica que el contenedor esté activo:
docker psDebe aparecer un contenedor llamado:
mongo-products-apiPaso 4: Probar la librería local
npm run test:utilsResultado esperado:
Producto válido: true
Nombre formateado: ARROZ
Valor inventario: 480
Tiene stock: true
Precio con descuento: 28.8Paso 5: Ejecutar la API
npm startResultado esperado:
MongoDB conectado correctamente
Servidor ejecutándose en http://localhost:30009. Flujo de trabajo de la práctica
Flujo general
1. El usuario hace una petición desde Insomnia
2. Express recibe la petición
3. El logger middleware registra la petición
4. Si la ruta está protegida, auth middleware valida la API Key
5. Si se crea un producto, validateProduct middleware valida el body
6. El controller recibe la petición
7. El service aplica la lógica de negocio
8. La librería local calcula y formatea datos
9. El repository guarda o consulta datos en MongoDB
10. MongoDB responde
11. La API devuelve una respuesta JSON10. Endpoints para Insomnia
URL base:
http://localhost:3000/apiEndpoint 1: Verificar API
Método
GETURL
http://localhost:3000/apiHeaders
No necesita headers.
Body
No lleva body.
Respuesta esperada
{
"success": true,
"message": "API Node.js con Express, MongoDB, Docker, SOLID y librería local funcionando correctamente"
}Endpoint 2: Obtener productos
Método
GETURL
http://localhost:3000/api/productsHeaders
No necesita headers.
Body
No lleva body.
Respuesta esperada
{
"success": true,
"message": "Lista de productos",
"products": []
}Endpoint 3: Crear producto
Método
POSTURL
http://localhost:3000/api/productsHeaders
Content-Type: application/json
x-api-key: 12345Body JSON
{
"name": " arroz ",
"price": 32,
"stock": 15
}Respuesta esperada
{
"success": true,
"message": "Producto creado correctamente",
"product": {
"name": "ARROZ",
"price": 32,
"stock": 15,
"inventoryValue": 480,
"hasStock": true,
"priceWithTenPercentDiscount": 28.8
}
}Qué demuestra este endpoint
Este endpoint demuestra que la librería funciona porque:
" arroz " se convierte en "ARROZ"
32 * 15 da 480
stock 15 devuelve true
32 con 10% de descuento da 28.8Endpoint 4: Obtener producto por ID
Método
GETURL
http://localhost:3000/api/products/ID_DEL_PRODUCTOEjemplo:
http://localhost:3000/api/products/66a123456789abcdef123456Headers
No necesita headers.
Body
No lleva body.
Respuesta esperada
{
"success": true,
"message": "Producto encontrado",
"product": {
"_id": "ID_DEL_PRODUCTO",
"name": "ARROZ",
"price": 32,
"stock": 15,
"inventoryValue": 480,
"hasStock": true,
"priceWithTenPercentDiscount": 28.8
}
}Endpoint 5: Eliminar producto
Método
DELETEURL
http://localhost:3000/api/products/ID_DEL_PRODUCTOHeaders
x-api-key: 12345Body
No lleva body.
Respuesta esperada
{
"success": true,
"message": "Producto eliminado correctamente",
"product": {
"_id": "ID_DEL_PRODUCTO",
"name": "ARROZ",
"price": 32,
"stock": 15,
"inventoryValue": 480,
"hasStock": true,
"priceWithTenPercentDiscount": 28.8
}
}11. Resumen de endpoints
| Método | Endpoint | Descripción | Requiere API Key |
|---|---|---|---|
| GET | /api | Verifica que la API funciona | No |
| GET | /api/products | Lista productos | No |
| GET | /api/products/:id | Busca producto por ID | No |
| POST | /api/products | Crea producto | Sí |
| DELETE | /api/products/:id | Elimina producto | Sí |
12. Comprobación completa del flujo
12.1 Crear producto
En Insomnia crea un producto con POST.
Body:
{
"name": " arroz ",
"price": 32,
"stock": 15
}12.2 Verificar transformación de datos
La respuesta debe mostrar:
{
"name": "ARROZ",
"inventoryValue": 480,
"hasStock": true,
"priceWithTenPercentDiscount": 28.8
}Esto confirma que la librería local se ejecutó correctamente.
12.3 Listar productos
Ejecuta:
GET http://localhost:3000/api/productsDebe aparecer el producto creado.
12.4 Buscar por ID
Copia el _id del producto y úsalo en:
GET http://localhost:3000/api/products/ID_DEL_PRODUCTO12.5 Eliminar producto
Usa el mismo _id en:
DELETE http://localhost:3000/api/products/ID_DEL_PRODUCTOCon header:
x-api-key: 1234512.6 Confirmar eliminación
Ejecuta otra vez:
GET http://localhost:3000/api/productsEl producto eliminado ya no debe aparecer.
13. Pruebas de errores
Error 1: Crear producto sin API Key
POST http://localhost:3000/api/productsRespuesta esperada:
{
"success": false,
"message": "No se envió la API Key"
}Error 2: Crear producto con datos incorrectos
Body incorrecto:
{
"name": "",
"price": "treinta",
"stock": 15
}Respuesta esperada:
{
"success": false,
"message": "Producto inválido. Debe enviar name como texto, price como número y stock como número"
}Error 3: Buscar ID que no existe
GET http://localhost:3000/api/products/66a123456789abcdef123456Respuesta esperada:
{
"success": false,
"message": "Producto no encontrado"
}14. Comandos útiles de Docker
Ver contenedores activos
docker psDetener MongoDB
docker compose downDetener MongoDB y borrar volumen de datos
docker compose down -vVer logs del contenedor
docker logs mongo-products-api15. Conclusión
En esta práctica se implementó una API funcional con Node.js y Express, conectada a MongoDB mediante Docker. Además, se aplicó una estructura por capas basada en principios SOLID, se implementaron middlewares para logs, autenticación y validación, y se integró una librería local npm para reutilizar funciones de inventario.
El flujo completo permite crear, consultar, buscar y eliminar productos desde Insomnia, guardando la información en MongoDB.
