Skip to content

Repositorio con el código solución al desafío 1: Roommates del módulo 8 Implementación de API backend Node Express

Notifications You must be signed in to change notification settings

waldohidalgo/desafio_roommates

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Solución al desafío Roommates

El presente repositorio contiene el código solución del desafío 1 del módulo 8 Implementación de API backend Node Express de la beca Desarrollo de aplicaciones Full Stack Javascript Trainee dictada por Desafío Latam

Tabla de Contenidos

Deploy

El proyecto es completamente funcional y lo he desplegado a Render en el siguiente link

Requerimientos

Requisitos 1 y 2 Requisitos 3 y 4

Diagrama de Flujo

1.Estado Inicial

Proyecto estado inicial

2.Alerta Creación exitosa de usuario

Alerta Creación exitosa de usuario

3.Alerta Creación exitosa de gasto

Alerta Creación exitosa de gasto

4. Agregación exitosa de gasto

Agregación exitosa de gasto

5.Alerta Edición exitosa de gasto

Alerta Edición exitosa de gasto

6.Alerta Eliminación exitosa de gasto

Alerta Eliminación exitosa de gasto

7.Ruta get roommates

Ruta get roommates

7.Ruta get gastos

Ruta get gastos

Soluciones

1. Ocupar el módulo File System para la manipulación de archivos alojados en el servidor. (3 Puntos)

He ocupado el módulo File System adaptado para trabajar con promesas tal y como muestro a continuación:

import { promises as fs } from "fs";

2. Capturar los errores para condicionar el código a través del manejo de excepciones. (1 Punto)

Todo mi código ya sea front end o back end utiliza bloques try y catch para el manejo de errores

3. El botón “Agregar roommate” de la aplicación cliente genera una petición POST (sin payload) esperando que el servidor registre un nuevo roommate random con la API randomuser, por lo que debes preparar una ruta POST /roommate en el servidor que ejecute una función asíncrona importada de un archivo externo al del servidor (la función debe ser un módulo), para obtener la data de un nuevo usuario y la acumule en un JSON (roommates.json)

El objeto correspondiente al usuario que se almacenará debe tener un id generado con el paquete UUID. (2 Puntos)

Para crear un usuario utilizando la API de Randomuser, he creado el siguiente código:

import { promises as fs } from "fs";
import path from "path";
import { v4 as uuidv4 } from "uuid";
import { calcularDebeHaber } from "./utils.js";
const crearUsuario = async () => {
  try {
    const id = uuidv4().slice(0, 8);

    const dataAPI = await fetch("https://randomuser.me/api/?results=1");
    const { results: data } = await dataAPI.json();
    const dataUsuario = data[0];
    const nombre = dataUsuario.name.first + " " + dataUsuario.name.last;
    const usuario = {
      id,
      nombre,
      debe: null,
      recibe: null,
    };
    const filePath = path.join(path.resolve(), "data", "roommates.json");
    const dataJSON = await fs.readFile(filePath, "utf-8");

    const dataParse = JSON.parse(dataJSON);
    dataParse.roommates.push(usuario);

    const filePathGastos = path.join(path.resolve(), "data", "gastos.json");
    const dataJSONGastos = await fs.readFile(filePathGastos, "utf-8");
    const dataParseGastos = JSON.parse(dataJSONGastos);
    const gastos = dataParseGastos.gastos;
    const nuevosRoommates = calcularDebeHaber(gastos, dataParse.roommates);
    const nuevoObjetoData = { roommates: nuevosRoommates };
    await fs.writeFile(
      filePath,
      JSON.stringify(nuevoObjetoData, null, 2),
      "utf-8",
    );
    return nuevoObjetoData;
  } catch (error) {
    return error;
  }
};

export default crearUsuario;

Dicho código lo utilizo en el siguiente middleware:

export async function postRoommate(req, res) {
  try {
    await crearUsuario();
    res.status(200).send("usuario creado");
  } catch (error) {
    res.status(500).send(error);
  }
}

La ruta que crea un usuario es la siguiente:

router.post("/roommate", postRoommate);

4. Crear una API REST que contenga las siguientes rutas

4.1. GET /gastos: Devuelve todos los gastos almacenados en el archivo gastos.json

He creado la siguiente ruta que devuelve todos los gastos almacenados en el archivo gastos.json:

router.get("/gastos", getGastos);

4.2. POST /gasto: Recibe el payload con los datos del gasto y los almacena en un archivo JSON (gastos.json)

La siguiente ruta me permite crear un gasto:

router.post("/gasto", postGasto);

4.3. PUT /gasto: Recibe el payload de la consulta y modifica los datos almacenados en el servidor (gastos.json)

La siguiente ruta me permite editar un gasto:

router.put("/gasto", updateGasto);

4.4. DELETE /gasto: Recibe el id del gasto usando las Query Strings y la elimine del historial de gastos (gastos.json)

La siguiente ruta me permite eliminar un gasto:

router.delete("/gasto", deleteGasto);

4.5. GET /roommates: Devuelve todos los roommates almacenados en el servidor (roommates.json). Se debe considerar recalcular y actualizar las cuentas de los roommates luego de este proceso. (3 Puntos)

La siguiente ruta me permite devuelve todos los roommates almacenados en el servidor (roommates.json):

router.get("/roommates", getRoommates);

5. Devolver los códigos de estado HTTP correspondientes a cada situación. (1 Punto)

He devuelto los códigos de estado para cada situación y procedo a manejarlos en el front end. A continuación muestro un ejemplo:

export async function getRoommates(req, res) {
  try {
    const filePath = path.join(path.resolve(), "data", "roommates.json");
    const dataJSON = await fs.readFile(filePath, "utf-8");
    const dataParse = JSON.parse(dataJSON);
    res.json(dataParse);
  } catch (error) {
    res.status(500).send(error);
  }
}

Extra: Reseteo de Data vía Ruta y vía intervalo cada 30 minutos

Creación de ruta reset para reseteo de data vía ruta:

router.get("/reset", resetData);

Para lo cual he creado el siguiente middleware:

export async function resetData(req, res) {
  try {
    await fs.writeFile(
      path.join(path.resolve(), "data", "roommates.json"),
      JSON.stringify({ roommates: [] }, null, 2),
      "utf-8",
    );
    await fs.writeFile(
      path.join(path.resolve(), "data", "gastos.json"),
      JSON.stringify({ gastos: [] }, null, 2),
      "utf-8",
    );
    res.status(200).send("Data reseteada 😄");
  } catch (error) {
    res.status(500).send(error);
  }
}

Y creación de un setInterval para reseteo de data cada 30 minutos:

setInterval(async () => {
  try {
    const resultado = await resetScript();
    if (resultado === "exito") {
      console.log("Data reseteada");
    } else {
      throw new Error("No se pudo resetear la data");
    }
  } catch (error) {
    console.error("Error al resetear la data", error.message);
  }
}, 1800000);

El cual hace uso de la siguiente función resetScript:

export async function resetScript() {
  try {
    await fs.writeFile(
      path.join(path.resolve(), "data", "roommates.json"),
      JSON.stringify({ roommates: [] }, null, 2),
      "utf-8",
    );
    await fs.writeFile(
      path.join(path.resolve(), "data", "gastos.json"),
      JSON.stringify({ gastos: [] }, null, 2),
      "utf-8",
    );
    return "exito";
  } catch (error) {
    return error;
  }
}

About

Repositorio con el código solución al desafío 1: Roommates del módulo 8 Implementación de API backend Node Express

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published