Mira como lo hice antes de ver la clase:















La eliminación de datos es una operación fundamental en cualquier aplicación que maneja información. En el contexto de desarrollo web, implementar correctamente la funcionalidad de borrado es esencial para mantener la integridad de los datos y proporcionar una experiencia de usuario completa. En esta ocasión, exploraremos cómo implementar la operación DELETE en nuestro CRUD (Create, Read, Update, Delete) utilizando Node.js y el manejo de archivos para almacenamiento local.
¿Cómo implementar la operación DELETE en nuestro CRUD?
Para completar nuestro CRUD, necesitamos implementar la funcionalidad de eliminación de usuarios. Esta operación nos permitirá eliminar registros específicos de nuestra base de datos local basada en archivos. Vamos a crear un nuevo punto de entrada en nuestra aplicación que manejará las solicitudes DELETE.
Primero, creamos nuestro archivo para manejar la eliminación:
// app.delete.js app.delete('/users/:id', (req, res) => { const userId = parseInt(req.params.id, 10); fs.readFile(usersFilePath, 'utf8', (err, data) => { if (err) { return res.status(500).json({ error: "Error con conexión de datos" }); } let users = JSON.parse(data); users = users.filter(user => user.id !== userId); fs.writeFile(usersFilePath, JSON.stringify(users, null, 2), (err) => { if (err) { return res.status(500).json({ error: "Error al eliminar usuario" }); } res.status(204).send(); }); }); });
En este código:
/users/:id que acepta el ID del usuario a eliminar¿Cómo funciona el filtrado de usuarios?
La parte clave de nuestra implementación es el método filter() que utilizamos para eliminar el usuario específico:
users = users.filter(user => user.id !== userId);
Este método crea un nuevo array que incluye todos los elementos que pasan la condición especificada. En nuestro caso, estamos manteniendo todos los usuarios cuyo ID no coincide con el ID que queremos eliminar. De esta manera, efectivamente eliminamos el usuario deseado del array.
Es importante entender que este enfoque no modifica el array original, sino que crea uno nuevo sin el elemento que queremos eliminar. Esto sigue el principio de inmutabilidad que es una buena práctica en programación.
¿Cómo probamos nuestra funcionalidad de eliminación?
Para probar nuestra implementación, utilizamos Postman:
/users/2)Si todo funciona correctamente, el usuario con el ID especificado será eliminado de nuestro archivo de usuarios.
¿Cómo se integra DELETE con el resto de operaciones CRUD?
Con la implementación de DELETE, ahora tenemos un CRUD completo para nuestra aplicación:
Cada una de estas operaciones sigue un patrón similar:
¿Qué desafíos quedan pendientes?
Como se mencionó en la clase, existe un reto pendiente relacionado con la funcionalidad de actualización (PUT). El problema está relacionado con el manejo de IDs duplicados. La solución implica modificar la lógica de actualización para asegurarse de que:
Este es un excelente ejercicio para practicar la manipulación de datos y la lógica de programación.
¿Qué sigue después de implementar el CRUD completo?
Una vez que tenemos nuestro CRUD básico funcionando, podemos avanzar hacia conceptos más avanzados como:
Estos temas nos permitirán construir aplicaciones más robustas, seguras y mantenibles.
La implementación de un CRUD completo es un hito importante en el desarrollo de aplicaciones web. Con estas operaciones básicas, podemos construir sistemas complejos que permiten a los usuarios interactuar con datos de manera efectiva. ¿Has implementado alguna solución interesante para el reto de actualización? Comparte tus ideas y soluciones en los comentarios.
La eliminación de datos es una operación fundamental en cualquier aplicación que maneja información. En el contexto de desarrollo web, implementar correctamente la funcionalidad de borrado es esencial para mantener la integridad de los datos y proporcionar una experiencia de usuario completa. En esta ocasión, exploraremos cómo implementar la operación DELETE en nuestro CRUD (Create, Read, Update, Delete) utilizando Node.js y el manejo de archivos para almacenamiento local.
Para completar nuestro CRUD, necesitamos implementar la funcionalidad de eliminación de usuarios. Esta operación nos permitirá eliminar registros específicos de nuestra base de datos local basada en archivos. Vamos a crear un nuevo punto de entrada en nuestra aplicación que manejará las solicitudes DELETE.
Primero, creamos nuestro archivo para manejar la eliminación:
// app.delete.js
app.delete('/users/:id', (req, res) => {
const userId = parseInt(req.params.id, 10);
fs.readFile(usersFilePath, 'utf8', (err, data) => {
if (err) {
return res.status(500).json({ error: "Error con conexión de datos" });
}
let users = JSON.parse(data);
users = users.filter(user => user.id !== userId);
fs.writeFile(usersFilePath, JSON.stringify(users, null, 2), (err) => {
if (err) {
return res.status(500).json({ error: "Error al eliminar usuario" });
}
res.status(204).send();
});
});
});
En este código:
/users/:id que acepta el ID del usuario a eliminarLa parte clave de nuestra implementación es el método filter() que utilizamos para eliminar el usuario específico:
users = users.filter(user => user.id !== userId);
Este método crea un nuevo array que incluye todos los elementos que pasan la condición especificada. En nuestro caso, estamos manteniendo todos los usuarios cuyo ID no coincide con el ID que queremos eliminar. De esta manera, efectivamente eliminamos el usuario deseado del array.
Es importante entender que este enfoque no modifica el array original, sino que crea uno nuevo sin el elemento que queremos eliminar. Esto sigue el principio de inmutabilidad que es una buena práctica en programación.
Para probar nuestra implementación, utilizamos Postman:
/users/2)Si todo funciona correctamente, el usuario con el ID especificado será eliminado de nuestro archivo de usuarios.
Con la implementación de DELETE, ahora tenemos un CRUD completo para nuestra aplicación:
Cada una de estas operaciones sigue un patrón similar:
Como se mencionó en la clase, existe un reto pendiente relacionado con la funcionalidad de actualización (PUT). El problema está relacionado con el manejo de IDs duplicados. La solución implica modificar la lógica de actualización para asegurarse de que:
Este es un excelente ejercicio para practicar la manipulación de datos y la lógica de programación.
Una vez que tenemos nuestro CRUD básico funcionando, podemos avanzar hacia conceptos más avanzados como:
Estos temas nos permitirán construir aplicaciones más robustas, seguras y mantenibles.
La implementación de un CRUD completo es un hito importante en el desarrollo de aplicaciones web. Con estas operaciones básicas, podemos construir sistemas complejos que permiten a los usuarios interactuar con datos de manera efectiva. ¿Has implementado alguna solución interesante para el reto de actualización? Comparte tus ideas y soluciones en los comentarios.
Mira como lo hice antes de ver la clase:


















De nuevo pondré mi solución de actualizar en esta clase. Fíjense en la parte seleccionada.

El problema de id lo resuelven los motores de bases de datos, pienso que una forma fácil de resolverlo es utilizar som(), pero esto lleva a leer el objeto completo, recorrerlo uno a uno hasta que la condición sea verdad, en definitiva, sería un desgaste y utilizar recursos a medida que los datos crecen...
La validación funciona para crear o eliminar.
async function deleteUser(req, res) {
try {
const userId = parseInt(req.params.id, 10);
const data = await fs.readFile(usersFilePath, 'utf-8');
let users = JSON.parse(data);
const validation = users.some(user => user.id === userId)
if(!validation){
return res.status(500).json({
status: "Id no existe, intenta eliminar otro id",
})
}
users = users.filter(user => user.id !== userId);
await fs.writeFile(usersFilePath, JSON.stringify(users, null, 2))
res.status(204).end(); //204 no content, no regresa información
} catch (error) {
res.json({message: error.message})
}
}

app.put("/users/:id", (req, res) => {
const buscarId = parseInt(req.params.id, 10);
const updateUser = req.body;
if (isNaN(buscarId) || buscarId <= 0) {
return res.status(400).json({ error: "ID inválido" });
}
fs.readFile(userfilePath, "utf-8", (err, data) => {
if (err)
return res.status(500).json({ error: "Error al leer los datos" });
let users;
try {
users = JSON.parse(data || "[]");
} catch {
return res.status(500).json({ error: "Error al interpretar el JSON" });
}
const index = users.findIndex((u) => u.id === buscarId);
if (index === -1) {
return res.status(404).json({ error: "Usuario no encontrado" });
}
// Validación: no permitir campos vacíos o null
const cleanedUser = Object.fromEntries(
Object.entries(updateUser).filter(
([, value]) => value !== null && value !== ""
)
);
users[index] = { ...users[index], ...cleanedUser };
fs.writeFile(userfilePath, JSON.stringify(users, null, 2), (err) => {
if (err)
return res.status(500).json({ error: "Error al actualizar usuario" });
res.json({
message: "Usuario actualizado correctamente",
user: users[index],
});
});
});
});
Update method:
function isUniqueNumericId(id, users, currentId = null) {
return (
typeof id === "number" &&
!users.some((user) => user.id === id && user.id !== currentId)
);
}
Update validation:
if (mode === "create" && !isUniqueNumericId(id, users)) {
return { valid: false, error: "ID must be a unique number" };
}
if (mode === "update" && !isUniqueNumericId(id, users, id)) {
return { valid: false, error: "ID conflicts with another user" };
}
Finish Invocar desde el app.js:
const validation = validateUser(newUser, users, "create");
const validation = validateUser(updatedUser, users, "update");
//Función para actualizar sin agregar nueva o que permita sobre el mismo id
function updateUser(user, users) {
const { name, email, id } = user;
if (!isValidName(name)) {
return {
isValid: false,
error: 'El nombre debe tener al menos 3 caracteres.'
};
}
if (!isValidEmail(email)) {
return { isValid: false, error: 'El correo electrónico no es válido.' };
}
const idExist = users.some(existingUser =>
existingUser.id === id &&
existingUser.id !== user.id
);
if ( idExist ) {
return { isValid: false, error : 'El Id debe ser numérico y único.'};
}
return { isValid: true };
}
//PUT en el acrhivo app.js
app.put('/users/:id', (req,res) => {
const newUser = req.body;
const userId = parseInt(req.params.id, 10);
const updatedUser = req.body;
fs.readFile(usersFilePath, 'utf-8', (err, data) => {
if (err) {
return res.status(500).json({ error: 'Error con conexión de datos.'});
}
let users = JSON.parse(data);
const validation = updateUser(newUser, users);
if(!validation.isValid) {
return res.status(400).json({ error: validation.error });
}
users= users.map(user =>
user.id === userId ? { ...user, ...updatedUser } : user
);
fs.writeFile(usersFilePath, JSON.stringify(users, null, 2), err => {
if (err) {
return res
.status(500)
.json({ error: 'Error al actualizar al usuario.' });
}
res.json(updatedUser);
});
});
});
Me encontre esta 💎 en internet investigando sobre validaciones en expressJS
La explicación del filtro en la línea 137 sería algo como "deja el usuario si el id es distinto del que se quiere eliminar". Así se elimina el del Id que coincide