npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

api-node-solid-mongo-manual

v1.0.0

Published

API sencilla con Node.js, Express, MongoDB en Docker, arquitectura SOLID y librería local

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.js

4. 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.js

Función: muestra en consola cada petición realizada.

Ejemplo:

[GET] /api/products
[POST] /api/products

5.2 Auth middleware

Archivo:

src/middlewares/auth.middleware.js

Función: protege endpoints que modifican datos usando una API Key.

Header requerido:

x-api-key: 12345

5.3 Validate product middleware

Archivo:

src/middlewares/validateProduct.middleware.js

Función: valida que el producto tenga datos correctos antes de guardarlo.


6. Librería local implementada

La librería se llama:

product-inventory-utils

Está ubicada en:

packages/product-inventory-utils

Funciones 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 version

8. Paso a paso para ejecutar el proyecto

Paso 1: Entrar a la carpeta del proyecto

cd api-node-solid-mongo-manual

Paso 2: Instalar dependencias

npm install

Este comando instala Express, Mongoose y también la librería local:

product-inventory-utils

Paso 3: Levantar MongoDB con Docker

docker compose up -d

Verifica que el contenedor esté activo:

docker ps

Debe aparecer un contenedor llamado:

mongo-products-api

Paso 4: Probar la librería local

npm run test:utils

Resultado esperado:

Producto válido: true
Nombre formateado: ARROZ
Valor inventario: 480
Tiene stock: true
Precio con descuento: 28.8

Paso 5: Ejecutar la API

npm start

Resultado esperado:

MongoDB conectado correctamente
Servidor ejecutándose en http://localhost:3000

9. 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 JSON

10. Endpoints para Insomnia

URL base:

http://localhost:3000/api

Endpoint 1: Verificar API

Método

GET

URL

http://localhost:3000/api

Headers

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

GET

URL

http://localhost:3000/api/products

Headers

No necesita headers.

Body

No lleva body.

Respuesta esperada

{
  "success": true,
  "message": "Lista de productos",
  "products": []
}

Endpoint 3: Crear producto

Método

POST

URL

http://localhost:3000/api/products

Headers

Content-Type: application/json
x-api-key: 12345

Body 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.8

Endpoint 4: Obtener producto por ID

Método

GET

URL

http://localhost:3000/api/products/ID_DEL_PRODUCTO

Ejemplo:

http://localhost:3000/api/products/66a123456789abcdef123456

Headers

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

DELETE

URL

http://localhost:3000/api/products/ID_DEL_PRODUCTO

Headers

x-api-key: 12345

Body

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/products

Debe 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_PRODUCTO

12.5 Eliminar producto

Usa el mismo _id en:

DELETE http://localhost:3000/api/products/ID_DEL_PRODUCTO

Con header:

x-api-key: 12345

12.6 Confirmar eliminación

Ejecuta otra vez:

GET http://localhost:3000/api/products

El producto eliminado ya no debe aparecer.


13. Pruebas de errores

Error 1: Crear producto sin API Key

POST http://localhost:3000/api/products

Respuesta 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/66a123456789abcdef123456

Respuesta esperada:

{
  "success": false,
  "message": "Producto no encontrado"
}

14. Comandos útiles de Docker

Ver contenedores activos

docker ps

Detener MongoDB

docker compose down

Detener MongoDB y borrar volumen de datos

docker compose down -v

Ver logs del contenedor

docker logs mongo-products-api

15. 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.