[Series Thực Chiến E-commerce] Bài 16: "Quay xe" sửa sai - API Cập nhật Thông tin Sản phẩm (Update Product)
Chào anh em!
Quay lại với kịch bản đau tim ở Bài 15: Nửa đêm, ông Admin mắt nhắm mắt mở đăng bán cái iPhone 15 Pro Max, thay vì gõ 30 củ thì ông ấy gõ nhầm thành... 3 củ. Sáng hôm sau dậy thấy hàng ngàn đơn đặt hàng, chắc chỉ có nước bán công ty đi mà đền!
Để cứu vãn những pha "đi vào lòng đất" như thế này, hệ thống của chúng ta bắt buộc phải có tính năng Cập nhật Sản phẩm (Update Product). Tốc độ sửa sai phải tính bằng giây!
Hôm nay, mình sẽ cùng anh em mổ xẻ đoạn code Update này. Điểm ăn tiền nhất nằm ở cách chúng ta xử lý cái trường slug nhé.
1. Não bộ xử lý (Controller) & Cái bẫy "Slug"
Anh em mở file controllers/product.js ra và thêm hàm updateProduct vào:
const slugify = require('slugify'); // Đảm bảo thư viện này vẫn đang được gọi nhé
const updateProduct = asyncHandler(async (req, res) => {
// Lấy ID sản phẩm từ trên thanh URL xuống
const { pid } = req.params;
// 💡 ĐIỂM SÁNG THỰC CHIẾN LÀ ĐÂY: Xử lý vụ đổi tên sản phẩm
if (req.body && req.body.title) {
// Nếu Admin gửi lên một cái 'title' mới, ta PHẢI tạo lại 'slug' cho nó
req.body.slug = slugify(req.body.title);
}
// Bắn data mới xuống Database để ghi đè
const updatedProduct = await Product.findByIdAndUpdate(
pid,
req.body,
{ new: true } // Vẫn là câu thần chú: Trả về data MỚI sau khi đã sửa xong
);
// Phản hồi lại cho Frontend kết quả
return res.status(200).json({
success: !!updatedProduct,
updatedProduct: updatedProduct || 'Cannot update products - Cập nhật thất bại',
});
});
module.exports = {
createProduct,
getProduct,
updateProduct, // Đừng quên ném nó ra ngoài
};
Tại sao cái if check req.body.title lại quan trọng?
Nhiều Newbie hay có thói quen bê nguyên cục req.body ném thẳng vào findByIdAndUpdate là xong. Nhưng anh em thử nghĩ xem:
Lúc đầu tên sản phẩm là "iPhone 15". Server tự tạo slug là iphone-15.
Sau đó Admin vào đổi tên thành "iPhone 15 Pro Max".
Nếu anh em không xử lý sinh lại slug, thì cái tên là "Pro Max" nhưng cái đường dẫn URL vẫn cứ là domain.com/product/iphone-15. Khách nhìn vào link tưởng lừa đảo, mà Google bot nó quét qua nó cũng đánh giá điểm SEO cực kỳ thấp vì URL chả liên quan gì đến nội dung.
Chỉ tốn thêm 3 dòng code if (req.body.title)... nhưng ứng dụng của anh em xịn xò và chuẩn chỉ hơn hẳn!
2. Dựng "Lô cốt" bảo vệ API (Router)
Sửa thông tin sản phẩm, đặc biệt là sửa Giá bán, là một quyền lực tối thượng. Khách hàng bình thường tuyệt đối không được rớ vào cái API này. Chúng ta lại phải gọi hai "anh bảo vệ" quen thuộc ra canh cửa thôi.
Anh em mở file routers/product.js:
const express = require('express');
const router = express.Router();
const ctrls = require('../controllers/product');
// Nhập khẩu đội bảo vệ từ module User sang
const { verifyAccessToken, isAdmin } = require('../middlewares/verifyToken');
router.post('/', [verifyAccessToken, isAdmin], ctrls.createProduct);
router.get('/:pid', ctrls.getProduct);
// Route Update: Bắt buộc phải là ADMIN
router.put('/:pid', [verifyAccessToken, isAdmin], ctrls.updateProduct);
module.exports = router;
Lời kết
Test trên Postman cực kỳ đơn giản. Anh em đăng nhập bằng tài khoản Admin lấy thẻ accessToken. Chọn một sản phẩm vừa thêm lúc nãy, bắn request PUT vàohttp://localhost:5000/api/product/cái-id-sản-phẩm với body là giá mới hoặc tên mới. Trả về data nhảy số chuẩn xác là anh em yên tâm chốt task được rồi.
Tuy nhiên, có những sản phẩm lỗi thời, công ty ngừng kinh doanh (ví dụ iPhone 4, iPhone 5 bây giờ đào đâu ra hàng mới mà bán). Admin không muốn cập nhật nữa, mà muốn XÓA SẠCH nó khỏi Database cho đỡ rác hệ thống.
Đó chính là lúc chúng ta cần đến Lession 17: Delete Product.
All rights reserved