Un CRUD de las siglas de Create, Read, Update, Delete (Crear, Leer, Modificar, Eliminar) nos permite gestionar los recursos de una aplicación.
Verbos HTTP
Hasta ahora sólo habíamos usado el método get, el cual nos permite acceder a la información. Los que vamos a ver en esta publicación son:
- GET → Recupera recursos
- POST → Agrega recursos
- PUT → Modifica recursos
- DELETE → Elimina recursos
Ordenar rutas
A medida que nuestro proyecto vaya creciendo, también lo harán las URL y nuestro archivo app.js terminará siendo caótico.
Para eso lo recomendable será ordenar nuestro código en archivos y directorios. Por ejemplo:

Helpers
Son funciones de uso habitual. Por ejemplo podemos tener un helper para obtener el formato de la fecha y hora actual. Dentro de src/helpers vamos a crear el archivo dateHelper.js:
exports.formatToday = () => {
const date = new Date();
return date.getFullYear() + "-" + (date.getMonth()+1) + "-" + date.getDate() + " " + date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds()
}
Modelos
Define la lógica para gestionar la información. Dentro de src/models creamos eventoModel.js:
//Conexión a la base de datos.
const connection = require('../../db');
//Helper para fechas
const {formatToday} = require('../helpers/dateHelper')
//Devuelve la lista completa de los eventos.
exports.all = async() => {
const query = `
SELECT id, nombre, cupo
FROM eventos
`;
try{
[results] = await connection.query(query);
return results;
}catch(error){
throw error;
}
}
//Crea un evento nuevo.
exports.create = async( {nombre, descripcion, cupo} ) => {
const query = `
INSERT INTO eventos(nombre, descripcion, cupo, fecha_creacion, fecha_modificacion)
VALUES(?, ?, ?, ?, ?)
`;
try{
await connection.query(query, [nombre, descripcion, cupo, formatToday(), formatToday()]);
}catch(error){
throw error;
}
}
//Recupera un evento por su ID.
exports.find = async(ID) => {
const query = `
SELECT id, nombre, cupo
FROM eventos
WHERE id = ?
`;
try{
[results] = await connection.query(query, [ID]);
return (results.length == 1) ? results[0] : null;
}catch(error){
throw error;
}
}
//Modifica un evento.
exports.update = async( {ID, nombre, descripcion, cupo} ) => {
const query = `
UPDATE eventos
SET
nombre = ?,
descripcion = ?,
cupo = ?,
fecha_modificacion = ?
WHERE id = ?
`;
try{
await connection.query(query, [nombre, descripcion, cupo, formatToday(), ID]);
}catch(error){
throw error;
}
}
//Elimina un evento.
exports.delete = async( ID ) => {
const query = `
DELETE FROM eventos
WHERE id = ?
`;
try{
await connection.query(query, [ID]);
}catch(error){
throw error;
}
}
Controladores
Define la lógica del sistema. Vamos al src/controllers y creamos eventoController.js:
const eventoModel = require('../models/eventoModel');
exports.index = async(req, res) => {
try{
const results = await eventoModel.all();
res.json({ success: true, results });
}catch(error){
console.log(error);
res.status(500).json({ success: false, message: 'Error al intentar recuperar los eventos' });
}
}
exports.store = async(req, res) => {
const {nombre, descripcion, cupo} = req.body;
try{
await eventoModel.create( {nombre, descripcion, cupo} );
res.json({ success: true, message: 'El evento se ha creado correctamente'});
}catch(error){
console.log(error);
res.status(500).json({ success: false, message: 'Error al intentar agregar el evento' });
}
}
exports.show = async(req, res) => {
const {ID} = req.params;
try{
const result = await eventoModel.find(ID);
if(result == null){
//El evento con ese ID no existe.
res.status(404).json({ success: false, message: 'El evento no existe o ha dejado de existir' });
}else{
res.json({ success: true, result });
}
}catch(error){
console.log(error);
res.status(500).json({ success: false, message: 'Error al intentar recuperar el evento' });
}
}
exports.update = async(req, res) => {
const { ID } = req.params;
const { nombre, descripcion, cupo } = req.body;
try{
eventoModel.update( {nombre, descripcion, cupo, ID} );
res.json({ success: true, message: 'El evento se ha modificado correctamente'});
}catch(error){
console.log(error);
res.status(500).json({ success: false, message: 'Error al intentar modificar el evento' });
}
}
exports.destroy = async(req, res) => {
const { ID } = req.params;
try{
eventoModel.delete( ID );
res.json({ success: true, message: 'El evento se ha eliminado correctamente'});
}catch(error){
console.log(error);
res.status(500).json({ success: false, message: 'Error al intentar eliminar el evento' });
}
}
Rutas
Definimos las rutas para usar los controladores. Dentro de src/routes eventoRoutes.js:
const express = require('express');
const router = express.Router();
//Controlador
const eventoController = require('../controllers/eventoController');
router.get('/eventos', eventoController.index);
router.post('/eventos', eventoController.store);
router.get('/eventos/:ID', eventoController.show);
router.put('/eventos/:ID', eventoController.update);
router.delete('/eventos/:ID', eventoController.destroy);
module.exports = router;
Agregando rutas a nuestra aplicación
Finalmente podemos eliminar las líneas de código que habíamos creado en la publicación pasada:
//Ejemplo de cómo recuperar una lista de registros.
app.get('/eventos', async (req, res) => {
const query = `
SELECT id, nombre, descripcion, cupo
FROM eventos
`;
try{
[results] = await connection.query(query);
res.json({ success: true, results });
}catch(error){
console.log(error);
res.status(500).json({ success: false, message: 'Error al intentar recuperar los eventos' });
}
});
//Ejemplo de cómo recuperar un registro por su ID.
app.get('/eventos/:ID', async (req, res) => {
const {ID} = req.params;
const query = `
SELECT id, nombre, descripcion, cupo
FROM eventos
WHERE id = ?
`;
try{
[results] = await connection.query(query, [ID]);
if(results.length < 1){
res.status(404).json({ success: false, message: 'El evento no existe' });
}else{
res.json({ success: true, result: results[0] });
}
}catch(error){
console.log(error);
res.status(500).json({ success: false, message: 'Error al intentar recuperar el evento' });
}
});
Y reemplazarlas por:
app.use(require('./src/routes/eventoRoutes'));
Verbos HTTP desde Postman
Vamos a empezar por listar todos los eventos, algo que ya habíamos hecho en la publicación pasada:

Como podemos ver, el verbo es GET, estamos accediendo a la lista de recursos (eventos)
Verbo POST
En el caso de querer agregar un recuso nuevo, tenemos que usar el verbo POST:

Además los verbos POST suelen ir acompañados de información (body), que entre otras cosas estará oculta en la URL. En nuestro caso en particular enviamos el nombre, descripción y cupo del evento.
Verbo GET
El verbo GET tiene la particularidad que puede contener información dinámica en la URL. Por ejemplo podemos ver el evento que acabamos de crear agregando el ID del mismo:

Verbo PUT
Como ya mencioné al principio de la publicación, el verbo PUT se utiliza para modificar un recurso. Debemos pasarle por la URL el evento que queremos modificar y también la información nueva en el cuerpo de la petición:

Verbo DELETE
Y finalmente cerramos el ciclo, eliminando el recuso:
