1

Crear un CRUD API REST + MVC + ES2024 con Express.js

<h1>Implementación de un CRUD en una estructura MVC en Express usando ES2024</h1>

Este tutorial te guiará a través de la implementación de un CRUD en Express, utilizando una estructura de carpetas moderna y siguiendo las últimas características de ECMAScript (ES). La aplicación almacenará los datos en un archivo db.json dentro de una carpeta database y aplicará el patrón de arquitectura MVC (Modelo-Vista-Controlador).

Estructura del Proyecto

Primero, organizamos nuestro proyecto siguiendo esta estructura:

/project-root
│
├── /database            # Carpeta para almacenamiento de datos
│   └── db.json          # Archivo JSON que almacena los datos
│
├── /src
│   ├── /controllers     # Controladores que manejan lalógica de negocio y peticiones HTTP
│   ├── /models          # Modelos que representan las entidades dela aplicación
│   ├── /routes          # Rutas que definen los endpoints dela API
│   └── index.js         # Punto de entrada dela aplicación
│
├── package.json
└── README.md

Paso 1: Crear db.json con Datos de Prueba

Primero, crea el archivo db.json dentro de la carpeta database con algunos datos de prueba. Este archivo será usado para almacenar los métodos de pago.

/database/db.json

{
  "paymentMethods": [
    {
      "id": 1,
      "type": "Credit Card",
      "provider": "Visa",
      "accountNumber": "**** **** **** 1234",
      "expiry": "12/24"
    },
    {
      "id": 2,
      "type": "PayPal",
      "provider": "PayPal",
      "accountNumber": "[email protected]",
      "expiry": ""
    }
  ]
}

Paso 2: Modificar el Modelo

El modelo se encargará de leer y escribir datos en db.json, utilizando fs/promises para manejar las operaciones de archivos de forma asíncrona.

/src/models/paymentMethodModel.js

import { promises as fs } from'fs';
import path from'path';
import { fileURLToPath } from'url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

classPaymentMethod{
  constructor() {
    this.filePath = path.join(__dirname, '../../database/db.json');
  }

  async _readData() {
    const data = await fs.readFile(this.filePath, 'utf-8');
    returnJSON.parse(data);
  }

  async _writeData(data) {
    await fs.writeFile(this.filePath, JSON.stringify(data, null, 2));
  }

  async findAll() {
    const data = awaitthis._readData();
    return data.paymentMethods;
  }

  async findById(id) {
    const data = awaitthis._readData();
    return data.paymentMethods.find(pm => pm.id === parseInt(id));
  }

  async create(paymentMethod) {
    const data = awaitthis._readData();
    const newMethod = {
      id: data.paymentMethods.length ? data.paymentMethods.length + 1 : 1,
      ...paymentMethod
    };
    data.paymentMethods.push(newMethod);
    awaitthis._writeData(data);
    return newMethod;
  }

  async update(id, updatedData) {
    const data = awaitthis._readData();
    const index = data.paymentMethods.findIndex(pm => pm.id === parseInt(id));
    if (index !== -1) {
      data.paymentMethods[index] = { id: parseInt(id), ...updatedData };
      awaitthis._writeData(data);
      return data.paymentMethods[index];
    }
    returnnull;
  }

  asyncdelete(id) {
    const data = awaitthis._readData();
    const index = data.paymentMethods.findIndex(pm => pm.id === parseInt(id));
    if (index !== -1) {
      data.paymentMethods.splice(index, 1);
      awaitthis._writeData(data);
      returntrue;
    }
    returnfalse;
  }
}

exportdefaultnew PaymentMethod();

Paso 3: Modificar el Controlador

El controlador manejará las solicitudes HTTP y delegará las operaciones de negocio al modelo.

/src/controllers/paymentMethodController.js

import PaymentMethod from'../models/paymentMethodModel.js';

classPaymentMethodController{
  async getAll(req, res) {
    const paymentMethods = await PaymentMethod.findAll();
    res.json(paymentMethods);
  }

  async getById(req, res) {
    const method = await PaymentMethod.findById(req.params.id);
    if (method) {
      res.json(method);
    } else {
      res.status(404).json({ message: 'Método de pago no encontrado' });
    }
  }

  async create(req, res) {
    const newMethod = await PaymentMethod.create(req.body);
    res.status(201).json(newMethod);
  }

  async update(req, res) {
    const updatedMethod = await PaymentMethod.update(req.params.id, req.body);
    if (updatedMethod) {
      res.json(updatedMethod);
    } else {
      res.status(404).json({ message: 'Método de pago no encontrado' });
    }
  }

  asyncdelete(req, res) {
    const success = await PaymentMethod.delete(req.params.id);
    if (success) {
      res.status(204).send();
    } else {
      res.status(404).json({ message: 'Método de pago no encontrado' });
    }
  }
}

exportdefaultnew PaymentMethodController();

Paso 4: Configurar las Rutas

Las rutas definen los endpoints de la API y asignan las rutas a los controladores correspondientes.

/src/routes/paymentMethodRoutes.js

import { Router } from'express';
import paymentMethodController from'../controllers/paymentMethodController.js';

const router = Router();

router.get('/', paymentMethodController.getAll);
router.get('/:id', paymentMethodController.getById);
router.post('/', paymentMethodController.create);
router.put('/:id', paymentMethodController.update);
router.delete('/:id', paymentMethodController.delete);

exportdefault router;

Paso 5: Configurar el Punto de Entrada index.js

Finalmente, el archivo index.js actuará como el punto de entrada de la aplicación y configurará las rutas.

/src/index.js

import express from'express';
import paymentMethodRoutes from'./routes/paymentMethodRoutes.js';

const app = express();
const port = 3002;

app.use(express.json()); // Para manejar JSON en las peticiones// Usar las rutas de paymentMethods
app.use('/payment-methods', paymentMethodRoutes);

app.listen(port, () => {
  console.log(`Servidor escuchando en http://localhost:${port}`);
});

Paso 6: Configurar package.json

Asegúrate de que tu package.json esté configurado para usar módulos ES:

package.json

{
  "type": "module",
  "scripts": {
    "start": "node src/index.js"
  },
  "dependencies": {
    "express": "^4.18.2"
  }
}

Consideraciones finales

Con estos pasos, has creado una API REST con Express bajo el patron MVC usando EcmaScript (ES2024) para métodos de pago, utilizando un archivo JSON para el almacenamiento de datos.

Puedes probar el CRUD usando herramientas como Postman o Bruno.

Escribe tu comentario
+ 2