0

[Series Thực Chiến E-commerce] Bài 15: "Show" hàng cho khách - API Lấy chi tiết một sản phẩm (Get Product By ID)

Chào anh em!

Ở Bài 14, ông Admin đã hì hục bưng hàng lên kệ (Database) thành công rồi. Bây giờ, đóng vai một khách hàng đang lướt web, thấy cái điện thoại xịn quá bèn click chuột vào để xem giá cả, mô tả chi tiết. Lúc này, Frontend sẽ gửi một yêu cầu réo rắt xuống Backend: "Ê server, lấy cho tao toàn bộ thông tin của cái sản phẩm có ID này coi!".

Bài toán hôm nay cực kỳ "nhẹ thở" nhưng lại là xương sống cho trang Chi tiết sản phẩm (Product Detail Page). Cùng xem thử đoạn code lấy dữ liệu siêu tốc bằng Mongoose nhé!

1. Hàm "Bốc hàng" theo ID (Controller)

Vì ở bài trước, mỗi sản phẩm khi tạo ra đều được MongoDB cấp cho một cái mã định danh duy nhất (_id). Do đó, để lấy chính xác sản phẩm khách cần, mình chỉ việc móc cái ID đó từ thanh URL xuống và dùng hàm findById() là xong.

Anh em mở file controllers/product.js và thêm đoạn này:

const Product = require('../models/product');
const asyncHandler = require('express-async-handler');

// ... (hàm createProduct bài trước)

const getProduct = asyncHandler(async (req, res) => {
  // Lấy ID sản phẩm từ URL (params)
  const { pid } = req.params;

  // Dùng Mongoose tìm đích danh document có ID đó
  const product = await Product.findById(pid);

  return res.status(200).json({
    success: product ? true : false,
    productData: product ? product : 'Cannot get product - Không tìm thấy sản phẩm',
  });
});

module.exports = {
  createProduct,
  getProduct, // Xuất xưởng
};

2. Mở cửa cho khách vào xem (Router) & Góc nhìn thực chiến

Giờ thì mang Controller ra cắm vào Router. Anh em tạo file routers/product.js nhé.

Điểm đặc biệt lưu ý: Xem chi tiết sản phẩm là hành động Công khai (Public). Bất kỳ ai vào web bán hàng cũng phải xem được sản phẩm, ép họ đăng nhập mới cho xem hàng thì khách chạy mất dép! Do đó, route này chúng ta tuyệt đối không bọc các middleware verifyAccessToken hay isAdmin nhé. Mở toang cửa luôn!

const express = require('express');
const router = express.Router();
const ctrls = require('../controllers/product');

// Route public: Lấy thông tin 1 sản phẩm
router.get('/:pid', ctrls.getProduct);

module.exports = router;

Góp ý nhỏ về chuẩn RESTful API cho anh em: Trong đoạn code anh em chuẩn bị, route được đặt là /getProducts/:pid. Tuy nó chạy hoàn toàn bình thường, nhưng nếu anh em đi phỏng vấn hoặc làm dự án thực tế, Leader thường sẽ bắt bẻ một chút. Theo chuẩn RESTful, URL nên dùng Danh từ thay vì Động từ, vì Động từ đã được thể hiện qua Method HTTP (như GET, POST, PUT, DELETE) rồi. Hơn nữa, ở routers/index.js bài trước mình đã khai báo gốc là /api/product rồi, nên vào đây mình chỉ cần để / hoặc/:pid là cực kỳ sạch sẽ và dễ hiểu. (Ví dụ: GET /api/product/123 là ngầm hiểu "Lấy thông tin sản phẩm có id 123" rồi).

Lời kết

Test thử thôi anh em! Lấy một cái _id sản phẩm trong database, bật Postman bắn request GET vào http://localhost:5000/api/product/cái-id-sản-phẩm-vào-đây. Một cục JSON chứa đầy đủ tên, giá, mô tả, màu sắc... trả về cái rụp là xong việc.

Nhưng đời không như mơ. Lỡ lúc đăng sản phẩm, Admin buồn ngủ gõ nhầm giá cái iPhone 15 từ 30 triệu thành... 3 triệu thì sao? Không sửa nhanh thì khách nó đặt hàng sập tiệm mất!

Bởi vậy, hệ thống bắt buộc phải có tính năng Cập nhật thông tin sản phẩm. Anh em chuẩn bị sẵn tinh thần và code cho Lession 16: Update Product nhé.


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.