¿Cómo funcionan los métodos de actualización y eliminación en APIs RESTful?
Los métodos de actualización y eliminación en APIs RESTful son esenciales para mantener la integridad de la información y asegurar la flexibilidad necesaria en nuestras aplicaciones. Utilizar de manera efectiva los métodos PATCH, PUT y DELETE puede marcar la diferencia en la forma en que interactuamos con los datos.
¿Cuáles son las principales diferencias entre PUT y PATCH?
Cuando nos encontramos con la necesidad de actualizar datos, disponemos de dos métodos fundamentalmente diferentes: PUT y PATCH.
PUT: Este método requiere el envío de todos los atributos del recurso, incluso si solo planeamos modificar uno de ellos. Imagina que tienes un producto con diez características; deberás enviar las diez al realizar la actualización, asegurándote de que cubrimos todos los aspectos del objeto.
PATCH: Un método mucho más flexible, permite enviar únicamente los atributos que deseamos modificar. Por ejemplo, si solo deseas cambiar el nombre de un producto, puedes enviar únicamente ese atributo. Esto ahorra tiempo y recursos, haciendo las actualizaciones más eficientes.
¿Cómo implementar un PATCH en nuestro código?
Implementar un PATCH es bastante similar a cómo se manejaría un POST, con la diferencia de que se requiere proporcionar un ID para identificar el recurso a actualizar.
app.patch('/products/:id',(req, res)=>{const{ id }= req.params;const newData = req.body;// Datos a actualizar// Lógica para actualizar el objeto con los datos proporcionados res.send(`Producto con ID ${id} ha sido actualizado.`);});
En este ejemplo, req.params se utiliza para obtener el ID del producto que se desea modificar, y req.body contiene los datos que queremos actualizar. Este enfoque asegura que solo los atributos enviados sean los que se actualicen.
¿Cómo se administra la eliminación de un recurso con DELETE?
El método DELETE es indispensable cuando queremos eliminar un recurso. La implementación es directa y no requiere un cuerpo de datos, solo el identificador del recurso que queremos eliminar.
app.delete('/products/:id',(req, res)=>{const{ id }= req.params;// Lógica para eliminar el producto con el ID proporcionado res.send(`Producto con ID ${id} ha sido eliminado.`);});
Con este enfoque, solo enviamos un identificador para el recurso a eliminar. Esta simplicidad es una de las fuerzas de REST, garantizando que las operaciones sean intuitivas y eficientes.
¿Cómo probar las solicitudes PATCH y DELETE?
Para probar las solicitudes PATCH y DELETE, herramientas como Insomnia pueden ser de gran ayuda. Al clonar el comportamiento existente, podemos enviar solicitudes de manera efectiva.
Probar PATCH: Configura una solicitud PATCH enviando solo los datos necesarios en el cuerpo. Asegúrate de incluir el ID en la ruta.
Probar DELETE: Configura una solicitud DELETE enviando únicamente el identificador en la ruta; no se requiere un cuerpo.
¿Qué es un CRUD y cómo se relaciona con estos métodos?
Un CRUD (Crear, Leer, Actualizar, Eliminar) representa las cuatro operaciones básicas que podemos realizar con un sistema de gestión de datos. Ahora, comprendiendo cómo utilizar PATCH, PUT y DELETE, puedes implementar completamente un CRUD en tus proyectos:
Create (Crear): A través de métodos POST.
Read (Leer): Mediante métodos GET, ya sea para obtener una lista de productos o un producto específico utilizando un ID.
Update (Actualizar): Utilizando PATCH para actualizaciones parciales o PUT para actualizaciones completas.
Delete (Eliminar): Con el método DELETE para la eliminación de recursos específicos.
Practicar estos métodos te permitirá crear endpoints robustos para diferentes dominios como categorías, órdenes y usuarios. Nunca dejes de aprender y explorar las posibilidades que REST y sus métodos te ofrecen. ¡Adelante!
router.get('/',(req, res)=>{const users =[];const{size}= req.query;const limit = size ||10;for(let i =0; i < limit; i++){ users.push({name: faker.name.firstName(),lastName: faker.name.lastName(),image: faker.image.imageUrl(),});} res.json(users);});
READ user
router.get('/:id',(req, res)=>{const{ id }= req.params; res.json({ id,name: faker.name.firstName(),lastName: faker.name.lastName(),image: faker.image.imageUrl(),});});
CREATE
router.post('/',(req, res)=>{const body = req.body; res.json({message:'Creation',data: body
});});
UPDATE
router.patch('/:id',(req, res)=>{const{ id }= req.params;const body = req.body; res.json({message:'Update',data: body, id
});});
DELETE
router.delete('/:id',(req, res)=>{const{ id }= req.params; res.json({message:'deleted element', id
});});module.exports= router;
excelente, muy bueno tu ejemplo, lo tomare como referencia también. Gracias.
Les recomiendo leer su propio código al retomar las clases!
Al menos yo no lo hacía y ahora comencé a hacerlo. No sólo se entienden más cosas, es como una inmersión previa para aprender nuevamente!
El profe Nicolás es muy buen docente y te permite aprender de forma didáctica estos temas que a veces pueden resultar un poco abstractos
La destructuracion es bastante poderosa. En el minuto: 2:58 en vez de hacerlo asi.
const{ id }= req.params;const body = req.body;
Lo hice de esta manera
const{ body,params:{ id }}= req;
Y el body y el id se pueden reutilizar de la misma manera, me parece bastante util que se puedan destructurar objectos mas complejos dentro de otros.
muy interesante !!!
Complementando al compañéro:
params: { id }: Esta parte de la desestructuración extrae la propiedad params del objeto req, y luego extrae la propiedad id del objeto params.
En Express, los parámetros de la URL se almacenan en la propiedad params, por lo que params: { id } representaría el valor del parámetro id den la URL de la solicitud.
RESUMEN:
PUT requiere enviar una representación completa del recurso que se está modificando, se debe implementar de forma idempotente y es adecuado para situaciones en las que una aplicación debe asegurarse que el estado final del recurso será idéntica a la que envía.
PATCH es adecuado para hacer modificaciones parciales, o para enviar un conjunto de instrucciones en lugar del resultado final.
DELETE no requiere de un formato en especial solo con el identificador para borrar un recurso en especifico.
Me quede con la duda sobre que pasa si queremos usar los métodos PUT, PATCH o DELETE sobre una ruta que tiene query params. ¿Los datos que queremos actualizar se pasan a través de query params o a través del body en JSON? Disculpen si es una pregunta muy tonta.
No hay ninguna pregunta tonta y además en una excelente pregunta. La respuesta es que normalmente cuando usas PUT, PATCH o DELETE pasas los datos que quieres actualizar por el body en JSON para que la información sensible no quede expuesta en la URL de la petición.
¡Muy bien! Gracias por la respuesta profesor. Me está encantando el curso :)
La verdad este es uno de los cursos que mas me ha gustado muy organizado
PUT
router.put('/:id',(req,res)=>{const{ id }= req.paramsconst body = req.body res.json({message:`update product with id ${id}`,data:{ id,...body
}})})
si visitamos con el método PUT la url "/api/v1/products/1" con el body
{"message":"update product with id 1","data":{"id":"1","name":"new product","price":3000,"image":"https://loremflickr.com/640/480"}}
PATCH
router.patch('/:id',(req,res)=>{const{ id }= req.paramsconst body = req.body res.json({message:`update parcial product with id ${id}`,data:{ id,...body
}})})
si visitamos con el método PATCH la url "/api/v1/products/1" con el body
{"name":"new name"}
obtendremos como respuesta de parte del servidor
{"message":"update parcial product with id 1","data":{"id":"1","name":"new name"}}
DELETE
router.delete('/:id',(req,res)=>{const{ id }= req.params res.json({message:`delete product with id ${id}`,})})
si visitamos con el método DELETE la url "/api/v1/products/1" obtendremos como respuesta de parte del servidor
{"message":"delete product with id 1"}
el archivo completo quedaría de esta manera
routes/product.router.js:
const express =require('express')const{ faker }=require('@faker-js/faker')const router = express.Router()router.get('/',(req,res)=>{const{ limit =10}= req.queryconst products =[]for(let i =0; i < limit; i++){ products.push({name: faker.commerce.productName(),price: faker.commerce.price(),image: faker.image.imageUrl()})} res.json(products)})router.get('/:id',(req,res)=>{const{ id }= req.params res.json({ id,})})router.post('/',(req,res)=>{const body = req.body res.json({message:"created",data: body
})})router.put('/:id',(req,res)=>{const{ id }= req.paramsconst body = req.body res.json({message:`update product with id ${id}`,data:{ id,...body
}})})router.patch('/:id',(req,res)=>{const{ id }= req.paramsconst body = req.body res.json({message:`update parcial product with id ${id}`,data:{ id,...body
}})})router.delete('/:id',(req,res)=>{const{ id }= req.params res.json({message:`delete product with id ${id}`,})})module.exports= router
SyntaxError: Unexpected token } in JSON at position 31
at JSON.parse (<anonymous>)
at parse (/mnt/c/Users/mateo/Documents/Platzi/my-store/node_modules/body-parser/lib/types/json.js:89:19)
at /mnt/c/Users/mateo/Documents/Platzi/my-store/node_modules/body-parser/lib/read.js:121:18
at invokeCallback (/mnt/c/Users/mateo/Documents/Platzi/my-store/node_modules/raw-body/index.js:224:16)
at done (/mnt/c/Users/mateo/Documents/Platzi/my-store/node_modules/raw-body/index.js:213:7)
at IncomingMessage.onEnd (/mnt/c/Users/mateo/Documents/Platzi/my-store/node_modules/raw-body/index.js:273:7)
at IncomingMessage.emit (events.js:203:15)
at endReadableNT (_stream_readable.js:1145:12)
at process._tickCallback (internal/process/next_tick.js:63:19)
No entiendo mi error.
Podrías compartir tu código para revisar el error
Lograste solucionar? si no es así, pon aquí tu código (puede ser en github) y lo miramos, suena a que tienes mal escrito tu json. verifícalo en esta página https://jsonformatter.curiousconcept.com/
Muy contenta con el aprendizaje que he obtenido de manera práctica y rápido sobre conceptos básicos del backend que son muy importantes más si eres frontend developer. XD
Es obligatorio el "message" en el JSON ? Porque yo lo saque y sigue funcionando. Tal vez es una convención o algo así.
Esperen... Si las convenciones de REST al final del día no son 100% obligatorias y como tal son más que todo una "guía"... ¿Eso quiere decir que es posible hacer que un PUT funcione como un PATCH, o incluso cosas más locas como que un GET funcione en realidad como un POST o como un DELETE? 😨.
·
Obviamente eso estaría mal, no tendría sentido alguno y probablemente solo confundirían a quienes quieren consumir nuestra api, je je, pero el punto principal de esta pregunta es... ¿Se puede hacer? ¿Esas cosas (dejando de lado el hecho de que no tienen mucho sentido en la prática) son posibles? ¿Se podría construir una API así? ¿O daría error? 👀.
Hola! Miguel
Si si se podría, pero, no es recomendable.
Es correcto
Si en una empresa definen trabajar con PUT de manera que cuando se use, se actualice el elemento en su totalidad. ¿Cómo hace el equipo para garantizar que efectivamente la petición contiene todos los atributos que ya tenía el elemento antes del PUT y no se está modificando nada más unos cuantos?
¡Hola! El PUT es para modificar TODO. Si se definió trabajar con PUT es porque saben que todos los registros se van a estar modificando constantemente, si habrá campos que no se van a modificar entonces necesitan trabajar con PATCH, no puedes usar PUT esperando solo modificar unos cuantos campos y dejando los demás tal cual 🤔
Este error pasa por que estamos usando http para mover nuestro express y al hacer la solicitud mediante postman o cualquier otro asistente estamos usando https
✔ Usando la extension RESTED en el navegador funciona igual que Insomnia
👇 aqui dejo el link
Muy bien al utilizar el pat, pach y delete! muy buen video.
Usando lo aprendido:
.
Categories
const categoriesData =['Sports','Books','Computing','Consoles and Videogames','Beauty and Personal Care','Children and Baby Toys',];
GET
router.get('/',(req, res)=>{const categories =[];for(let i =0; i < categoriesData.length; i++){ categories.push({categoryName: categoriesData[i],});} res.json(categories);});
CREATE
router.post('/',(req, res)=>{const body = req.body; res.json({message:'created',data: body,});});
UPDATE (PATCH)
router.patch('/:id',(req, res)=>{const{ id }= req.params;const body = req.body; res.json({message:'update',data: body, id,});});
DELETE
router.delete('/:id',(req, res)=>{const{ id }= req.params; res.json({message:'deleted', id,});});module.exports= router;