Curso de Backend con Node.js: API REST con Express.js

Toma las primeras clases gratis

COMPARTE ESTE ARTÍCULO Y MUESTRA LO QUE APRENDISTE

<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 la lógica de negocio y peticiones HTTP
│   ├── /models          # Modelos que representan las entidades de la aplicación
│   ├── /routes          # Rutas que definen los endpoints de la API
│   └── index.js         # Punto de entrada de la 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": "user@example.com",
      "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);

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

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

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

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

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

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

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

  async delete(id) {
    const data = await this._readData();
    const index = data.paymentMethods.findIndex(pm => pm.id === parseInt(id));
    if (index !== -1) {
      data.paymentMethods.splice(index, 1);
      await this._writeData(data);
      return true;
    }
    return false;
  }
}

export default new 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';

class PaymentMethodController {
  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' });
    }
  }

  async delete(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' });
    }
  }
}

export default new 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);

export default 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.

Curso de Backend con Node.js: API REST con Express.js

Toma las primeras clases gratis

COMPARTE ESTE ARTÍCULO Y MUESTRA LO QUE APRENDISTE

0 Comentarios

para escribir tu comentario

Artículos relacionados