Repository navigation
Instalaciones y Configuraciones
Para crear nuestra base de datos debemos tener instalado Node y MongoDB.
Nuestro primer paso es clonar el proyecto desde el repositorio de GitHub.
Dentro del directorio del proyecto, verificamos que exista el archivo package.json. Este archivo contiene una lista de dependencias necesarias para el proyecto. Para instalar todas estas dependencias ejecutamos el siguiente comando:

Este comando leerá el archivo package.json y descargará e instalará automáticamente todas las dependencias listadas en el proyecto. Es importante destacar que esto solo instalará las dependencias que ya están especificadas en el archivo package.json, por lo que no se descargarán dependencias adicionales.
Definimos un modelo de datos para nuestros productos dentro de Product.js dentro del directorio llamado models .
Configuramos Mongoose para que utilice la promesa global de Node.js en lugar de una implementación de promesas específica. Esto asegura que Mongoose trabaje de manera consistente con el entorno de Node.js y con las promesas en operaciones asincrónicas, como las operaciones de base de datos, dentro de la aplicación.

Definimos el esquema para el modelo de datos Product cuyas propiedades son:
title: Una cadena de texto que representa el título del producto. Es un campo obligatorio (required: true).
price: Un número en formato de cadena que representa el precio del producto. Tiene un valor predeterminado de 0, es obligatorio (required: true) y se le aplica la opción trim: true para eliminar espacios en blanco innecesarios alrededor del valor.
category: Una cadena de texto que representa la categoría del producto. Es un campo obligatorio (required: true).
offer: Un campo booleano que puede indicar si el producto está en oferta o no.
images: Un arreglo de cadenas de texto que almacena las URL de las imágenes asociadas al producto.
stock: Un número que representa la cantidad de unidades disponibles en stock. Es un campo obligatorio (required: true).
description: Una cadena de texto que almacena una descripción del producto. Se le aplica la opción trim: true para eliminar espacios en blanco innecesarios.
createdAt: Una cadena de texto que se utiliza para almacenar la fecha de creación del producto. No se define como obligatorio.

Finalmente, definimos un índice de texto completo en el campo title del modelo Product que permitirá realizar búsquedas de texto eficientes.

Además se exporta el modelo Product, lo que permite usarlo en otras partes de la aplicación para interactuar con la base de datos y realizar operaciones como crear, leer, actualizar y eliminar productos en la colección Product.

Para configurar la conexión a la base de datos creamos un archivo llamado db.js que será el punto de entrada de la aplicación. En este código se establece la conexión a la base de datos.
Comenzamos importando la biblioteca mongoose.

Se establece la conexión a la base de datos utilizando el método connect de mongoose.
Se proporciona la URL de conexión a la base de datos como argumento, la cual debe contener el nombre de usuario y la contraseña para acceder a dicha base de datos, así como la dirección del servidor MongoDB.
La opción { useNewUrlParser: true } se utiliza para evitar advertencias relacionadas con la configuración del analizador de URL.

Agregamos un controlador de eventos para el evento ‘error’ de la conexión de mongoose y si hay un error durante la conexión se mostrará un mensaje en la consola:

Se requiere el archivo que define el esquema y modelo de datos para los productos en la base de datos. Esto se hace para poder interactuar con la colección de productos.

Dentro de la carpeta Server, en el index.js, utilizamos el framework Express para crear un servidor web listo para manejar solicitudes HTTP y que se comunique con la base de datos (cuya configuración se encuentra en el archivo db.js). Para ello:
Se importan las bibliotecas necesarias:
express: Se importa el módulo de Express, que se utiliza para crear y configurar la aplicación web.
body-parser: Se importa el módulo de body-parser, que se utiliza para analizar las solicitudes entrantes y extraer datos del cuerpo de la solicitud, como datos JSON o datos de formulario.cors.
Se importa el módulo cors, que se utiliza para habilitar el intercambio de recursos entre dominios y permite que el servidor web sea accesible desde diferentes orígenes.

Se requiere un archivo de configuración de la base de datos. Se importa la configuración de la base de datos desde el archivo db.js

Se importan las rutas definidas. Se importan las rutas definidas para la aplicación desde el archivo index.js. Las rutas son utilizadas para definir cómo la aplicación responde a diferentes solicitudes HTTP, como GET, POST, PUT, DELETE, etc.

Se crea una instancia de la aplicación Express que se utilizará para configurar rutas y manejar solicitudes HTTP y se establece un puerto (5000) para la aplicación que escuchará las solicitudes entrantes.

Se configuran los middleware para analizar datos en las solicitudes entrantes, habilita CORS, establece el uso de las rutas definidas y finalmente inicia el servidor Express para escuchar las solicitudes entrantes en el puerto 5000. Esto permite que la aplicación atienda solicitudes HTTP y ejecute la lógica correspondiente para manejar esas solicitudes.

app.use(bodyParser.json()): Aquí se configura un middleware para analizar datos en formato JSON en las solicitudes entrantes. Esto permite que la aplicación pueda interpretar datos JSON enviados en el cuerpo de las solicitudes.
app.use(bodyParser.urlencoded({ extended: true })): Se configura otro middleware para analizar datos de formulario en las solicitudes entrantes. Esto es útil cuando los datos se envían a través de formularios HTML. El parámetro extended se establece en true, lo que permite analizar datos complejos codificados en formularios.
app.use(cors()): Este middleware habilita CORS (Cross-Origin Resource Sharing), lo que permite que el servidor sea accesible desde diferentes dominios o servidores web. Esto es útil si planeamos permitir que otras aplicaciones o sitios web accedan a tus rutas y recursos.
app.use(routes): Aquí se establece que la aplicación Express debe utilizar las rutas definidas Esto significa que las rutas que definiste para manejar diferentes tipos de solicitudes HTTP, como GET, POST, etc., estarán disponibles y se ejecutarán cuando se hagan solicitudes correspondientes a esas rutas.
app.listen(PORT, err => { /* ... */ }): En este bloque, se inicia el servidor Express y se pone a la escucha en el puerto 5000 y si ocurre algún error al iniciar el servidor, se captura y se muestra en la consola. Si no hay errores, se muestra un mensaje que indica que el servidor está en funcionamiento en el puerto especificado.
En el archivo index.js dentro de la carpeta routes establecemos las rutas de la aplicación relacionadas con los productos y asociamos cada ruta con una función de controladores de productos para manejar las solicitudes entrantes. Esto permite una organización clara y modular de nuestra aplicación, donde cada ruta tiene su propia función de controlador para realizar operaciones específicas en la base de datos.
const express = require('express'): Se importa la biblioteca Express, que se utiliza para crear y configurar rutas en la aplicación.
const productController = require('../controllers/ProductController.js'): Aquí se importa el controlador de productos, que contendrá la lógica para manejar las solicitudes relacionadas con los productos. El archivo del controlador se encuentra en la ruta '../controllers/ProductController.js'.
const router = express.Router(): Se inicializa un enrutador utilizando Express. El enrutador se utilizará para definir las rutas y las acciones que deben llevarse a cabo cuando se accede a esas rutas.

Definición de rutas:
router.get('/products', productController.getAllProducts): Esta ruta responde a las solicitudes GET a '/products' y llama a la función getAllProducts del controlador de productos para obtener todos los productos.
router.get('/product/:id', productController.getOneProduct): Esta ruta responde a las solicitudes GET a '/product/:id' y llama a la función getOneProduct del controlador para obtener un producto específico por su ID.
router.get('/products/:categoria', productController.getProductsByCategory): Esta ruta permite obtener productos por categoría, llamando a la función getProductsByCategory del controlador.
router.get('/product/get-offered', productController.getOfferedProducts): Permite obtener los productos en oferta llamando a la función getOfferedProducts del controlador.
router.get('/product/get-random', productController.getRandomProduct): Permite obtener un producto aleatorio llamando a la función getRandomProduct del controlador.
router.get('/product/search', productController.searchProduct): Esta ruta permite buscar productos llamando a la función searchProduct del controlador.

module.exports = router: Finalmente, el enrutador se exporta para que esté disponible en otros módulos de la aplicación. El controlador de productos (importado anteriormente) se encargará de la lógica real detrás de estas rutas.

Una vez configurados los pasos anteriores podemos ejecutar la aplicación utilizando el siguiente comando:

Esto iniciará el servidor y establecerá la conexión con la base de datos