En este proyecto se dará a conocer la construcción de una aplicación de servicios de Reservas Hoteleras
este trabajo se realizará en el editor de código Visual Studio Code
en el cual trabajaremos con Node.js
y Express
y utilizaremos el lenguaje de programación JavaScript. A continuación, se mostrarán los requisitos requeridos para construir este proyecto y su paso a paso de su realización.
-
Construir una aplicación de servicios para la gestión de reservas en hoteles que involucre las 4 operaciones CRUD y otras 6 adicionales relacionadas con filtros, utilizando Node.js y Express.
-
Opcionalmente, realizar un proceso de investigación relacionado con la documentación de API, usando Swagger, con la estandarización OPENAPI, la cual se utiliza en equipos internacionales para construir servicios escalables.
-
Utilizar Node.js y Express para el desarrollo del servidor.
-
Contar con un archivo .env para las variables de entorno, el cual establecerás el puerto.
-
Contar con un archivo .gitignore que incluya las carpetas y archivos que deberán ocultarse para el repositorio.
-
Usar una arquitectura de carpetas clara.
Implementación de los siguiente Endpoints:
-
Permitir la creación de reservas con los detalles necesarios (por ejemplo, hotel, tipo de habitación, número de huéspedes, fechas, etc.).
-
Permitir la visualización de la lista de reservas.
-
Permitir la obtención de la información de una reserva específica.
-
Permitir la actualización de la información de una reserva.
-
Permitir la eliminación de una reserva.
-
Permitir la búsqueda de reservas por hotel, rango de fechas, tipo de habitación, estado y número de huéspedes.
-
Almacenar los datos de las reservas en una estructura de datos.
Antes de comenzar a construir este proyecto debemos primero nuestra carpeta en donde se ejecutará nuestro proyecto desde la terminal e instaleremos todas las herramientas a utilizar en el proyecto como se muestra a continuación:
Después Estructuramos y creamos por patrón modular el orden de nuestras carpetas y archivos como se muestra en la imagen:
En nuestro archivo package.json
establecemos el script start
(nodemon) para usarlo en producción y tendremos además la instalación de cada una de las dependencias que requiere el proyecto.
Luego establecemos nuestro código en cada una de las carpetas y archivos creados, primero tendremos el código del patrón vista en el archivo index.js
como acceso principal.
// Patrón Vista
// Importar librerias a utilizar
const express = require (`express`);
const app = express ();
const cors = require (`cors`);
// Cargar variables de entorno en el archivo .env
require(`dotenv`).config();
// Importar rutas
const router = require(`./routes/routerReserva`);
//Añadir middleware
app.use(express.json());
app.use(express.urlencoded({ extended : true}));
app.use(process.env.URL_BASE + `/`, router);
app.use(cors());
app.listen(process.env.PORT, () => {
console.log(`listent in port ${process.env.PORT}`);
});
En el archivo .env
establecemos el puerto y la URL que utilizaremos en el proyecto.
#Designar el puerto.
PORT= 3000
# Designar base url
URL_BASE=/api
En el archivo modelReserva.js
creamos la clase reservations
que contendra todas las propiedades y atributos que utilizaremos para crear las reservas del hotel.
//Patrón Modelo
class Reservation {
constructor (id, nameHotel, numberGuests, typeRoom, checkIn, checkOut, name, email, paymentStatus){
this.id = id;
this.nameHotel = nameHotel;
this.numberGuests = numberGuests;
this.typeRoom = typeRoom;
this.checkIn = checkIn;
this.checkOut = checkOut;
this.name = name;
this.email = email;
this.paymentStatus = paymentStatus
}
getInfo () {
return (`Nombre: ${this.name} Email: ${this.email} Nombre hotel: ${this.nameHotel} Fecha de entrada: ${this.checkIn} Fecha de salida: ${this.checkOut} Tipo de habitación: ${this.typeRoom} Numero de personas: ${this.numberGuests} Estado de pago: ${this.paymentStatus}`);
}
}
// Exportar objetos
module.exports = Reservation ;
Después estableceremos las rutas de peticiones CRUD
en nuestro archivo routerReservas.js.
const express = require(`express`);
//creación de router express
const router = express.Router();
const reservationController = require(`../controllers/controllerReserva`);
// Realizar ruteo de peticiones
router.post(`/reservas`, reservationController.createReservation);
router.get(`/reservas`, reservationController.readAllReservation);
router.get(`/reservas/:id`, reservationController.readOneReservationById);
router.put(`/reservas/:id`, reservationController.updateReservation);
router.delete(`/reservas/:id`, reservationController.deleteReservation);
router.get(`/search`, reservationController.filterReservation);
//exportar modulo para utilizarlo en otras aplicaciones
module.exports = router;
Una vez establecida nuestras rutas, se realiza el código en la carpeta controllers en el archivo controllerReserva.js
.
//Patrón Controlador
// Importar librerias a utilizar
const Reservation = require(`../model/modelReserva`);
const dayjs = require(`dayjs`);
const { v4: uuidv4} = require("uuid");
// Crearemos un arreglo vacío donde se puedan ir agregando las reservas.
//1.- Crear nuevas reservas del hotel.
let reservations = [] ;
exports.createReservation = async (req, res) => {
const {nameHotel, numberGuests, typeRoom, checkIn, checkOut, name, email, paymentStatus } = req.body;
console.log( `Datos Recibidos:`, req.body);
// Dar formatos a las fechas
const parsedCheckIn = dayjs(checkIn).format(`DD/MM/YYYY`);
const parsedCheckOut = dayjs(checkOut).format(`DD/MM/YYYY`);
// verificar fechas convertidas
console.log(`Fecha de llegada:`, parsedCheckIn);
console.log(`Fecha de salida:`, parsedCheckOut);
// Ocuparemos la libreria uuidv4 para agregar id a las reservas creadas.
const newReservation = new Reservation (
uuidv4 (),
nameHotel,
parsedCheckIn,
parsedCheckOut,
numberGuests,
typeRoom,
name,
email,
paymentStatus
);
reservations.push(newReservation);
console.log(`Reservas:`, reservations);
res.status(201).json({
msg: `Reserva creada con éxito`,
data: newReservation,
});
};
//2.- Obtener lista de reservas.
exports.readAllReservation = async (req, res) => {
res.json ({
msg: `Reservas obtenidas con éxito`,
data: reservations,
});
};
//3.- Obtener información de una reserva en especifico.
exports.readOneReservationById = async (req, res) => {
const reservationId = req.params.id;
const reservation = reservations.find(reservation => reservation.id === reservationId);
if (!reservation) {
return res.status(404).json({msg: `Reserva no encontrada`})
}
res.json({
msg: `Reserva obtenida con éxito.`,
data: reservation,
});
};
//4.- Actualización de información de una reserva.
exports.updateReservation = async (req, res) => {
const reservationId = req.params.id;
const reservationIndex = reservations.findIndex(reservation => reservation.id === reservationId);
if (reservationIndex === -1){
return res.status(404).json({msg: `Reserva no encontrada`});
}
// spread operator (operador de propagación)
reservations[reservationIndex] = { ...reservations[reservationIndex], ...req.body}
return res.json({
msg: `Reserva modificada con éxito.`,
data: reservations[reservationIndex],
})
};
//5.- Eliminar una reserva del hotel
exports.deleteReservation = async (req, res) => {
const reservationId = req.params.id;
const reservationIndex = reservations.findIndex(reservation => reservation.id === reservationId);
if(reservationIndex === -1) {
return res.status(404).json({msg: `Reserva no encontrada`});
}
reservations.splice(reservationIndex, 1)
res.json({ msg: `Reserva eliminada con éxito.`})
};
//6.- Realizar busqueda de reservas por filtros.
exports.filterReservation = async (req, res) => {
const {nameHotel, numberGuests, typeRoom, checkIn, checkOut, paymentStatus } = req.query
const filteredRerservations = reservations.filter((reservation) => {
if (nameHotel && reservation.nameHotel !== nameHotel){
return false;
}
if (numberGuests && reservation.numberGuests !== parseInt(numberGuests)) {
return false;
}
if (typeRoom && reservation.typeRoom !== typeRoom) {
return false;
}
if (checkIn && reservation.checkIn !== checkIn) {
return false;
}
if (checkOut && reservation.checkOut !== checkOut) {
return false;
}
if (paymentStatus && reservation.paymentStatus !== paymentStatus){
return false;
}
return true;
});
if (filteredRerservations.length === 0) {
return res.status(404).json({ msg: `Reserva no encontrada`});
}
res.json ({
msg: `Reservaciones filtradas con éxito.`,
data: filteredRerservations
});
}
Ahora que tenemos todo el código ya escrito en cada archivo correspondiente por medio de la herramienta ThunderClient
simularemos la llamada a nuestras APIS.
Para poder probar el proyecto se creó un archivo llamado prueba.json
con el fin de poder simular y probar las distintas peticiones creadas.
[
{
"nameHotel":"Hotel Paraíso",
"numberGuests": "2",
"typeRoom": "Doble",
"checkIn": "2024-04-10",
"checkOut": "2024-04-30",
"name": "Leila Fernández",
"email": "[email protected]",
"paymentStatus": "pagado"
},
{
"nameHotel":"Hotel Paraíso",
"numberGuests": "1 personas",
"typeRoom": "Individual",
"checkIn": "2024-03-05",
"checkOut": "2024-04-01",
"name": "Magdalena Sanhueza",
"email": "[email protected]",
"paymentStatus": "pagado"
},
{
"nameHotel":"Hotel Paraíso",
"numberGuests": "3 personas",
"typeRoom": "Doble",
"checkIn": "2024-05-21",
"checkOut": "2024-05-30",
"name": "Irene Guzmán",
"email": "[email protected]",
"paymentStatus": "pagado"
},
{
"nameHotel":"Hotel Paraíso",
"numberGuests": "1 personas",
"typeRoom": "Suite",
"checkIn": "2024-06-17",
"checkOut": "2024-06-27",
"name": "Yoselyn Navarrete",
"email": "[email protected]",
"paymentStatus": "pagado"
}
]
1.- Primero utilizaremos el Create Reservation
para crear una reserva. Creamos un new request con una petición POST
. Realizaremos la creación de dos reservas como se muestran en las siguientes imagenes:
2.- Utilizaremos ahora el Read All Reservation
el cual nos traera en un arreglo todas las reservas creadas (que en este caso solo creamos 2 reservas). Creamos un new request con una petición GET
3.- Luego utilizaremos el Read One Reservation
el cual por medio de un id
nos traera solo una reserva en especifica. Creamos un new request con una petición GET
como se muestran en las siguientes imagenes:
4.- Ahora utilizaremos el Update Reservation
el cual nos permitira modificar cambios en alguna reserva en este caso cambiaremos el nombre del cliente y lo haremos también requiriendo un id
. Creamos un new request con una petición PUT
, como se muestran en las siguientes imagenes:
5.- Por último utilizaremos el Delete Reservation
para eliminar una reserva, requiriendo un id
. Creamos un new request con una petición DELETE
, como se muestran en las siguientes imagenes: