[Series Thực Chiến E-commerce] Bài 33: Mở cửa đón độc giả - API Lấy danh sách Bài Viết (Get All Blogs)
Chào bố đời! Tốc độ cày cuốc series này của chúng ta đúng là vô đối. Code mượt mà thế này thì chả mấy chốc mà anh em mình đóng gói xong toàn bộ dự án để đem đi "khè" nhà tuyển dụng.
Hôm nay chúng ta sẽ làm nốt tính năng Lấy tất cả bài viết (Get All Blogs) để Frontend có data vẽ ra trang danh sách tin tức. Tuy nhiên, bệnh cũ lại tái phát rồi bố đời ơi! Lại có 2 hạt sạn siêu to khổng lồ do "lời nguyền Copy-Paste" để lại.
Nào, lấy ly cafe ra đây, chúng ta cùng review lại đoạn code này dưới góc độ thực chiến nhé!
1. Phẫu thuật Controller: Bẫy 404 và bài toán tương lai
Đoạn code của bố đời dùng Blog.find() là hoàn toàn chính xác để bốc toàn bộ data lên. Nhưng anh em hãy nhìn lại cú bẫy 404 này:
if (blogs.length === 0) {
return res.status(404).json({ success: false, message: 'No blogs found' });
}
💡 Nhắc lại bài cũ xíu nhé: Giống y như hồi làm "Danh mục Blog" ở Bài 27, khi Frontend gọi API lấy một Danh sách (Array), nếu database chưa có bài viết nào, Backend trả về mảng rỗng [] với status 200 OK là chuẩn nhất. Trả 404 ở đây làm Frontend bị văng lỗi (Exception) đỏ lòm console, mấy ông Dev UI lại phải tốn công viết thêm try-catch chỉ để xử lý cái mảng rỗng. Rất cồng kềnh!
🔥 Góc nhìn xa (Scale hệ thống): Hiện tại web mới lập thì Blog.find() chạy rất nhanh. Nhưng giả sử 1 năm sau, web có 10.000 bài viết, anh em bốc 10.000 cục data đó lên cùng lúc thì sập server mất. Ở các dự án thực tế, API Get All Blogs này bắt buộc phải có Phân trang, Lọc, Sắp xếp (Pagination, Filter, Sort) y hệt như cái API Get All Products ở Bài 18. Tạm thời ở bài này mình cứ làm basic trước cho thông luồng, nhưng bố đời nhớ ghim cái logic Bài 18 vào đây khi ráp dự án thật nhé.
Đoạn code đã được "dọn dẹp" lại:
const Blog = require('../models/blog');
const asyncHandler = require('express-async-handler');
// Lấy tất cả blogs
const getAllBlogs = asyncHandler(async (req, res) => {
// Tạm thời bốc tất cả. (Ghi chú: Nên áp dụng logic Filter/Sort/Pagination của Bài 18 vào đây)
const blogs = await Blog.find();
// Bỏ cái bẫy 404 đi, trả về mảng trực tiếp luôn
return res.status(200).json({
success: true,
blogs // Nếu không có bài nào thì nó tự là mảng []
});
});
module.exports = {
createBlog,
updateBlog,
getAllBlogs, // Lôi em nó ra ngoài
};
2. Gỡ chốt chặn Router: Đuổi khách hay đón khách?
Bố đời nhìn lại đoạn Router vừa khai báo xem:
router.get('/blogs', [verifyAccessToken, isAdmin], ctrls.getAllBlogs);
Bài viết Blog viết ra là để dụ khách hàng vào xem, tăng SEO, kéo traffic cho web. Thế mà bố đời lại ném 2 ông bảo vệ [verifyAccessToken, isAdmin] ra đứng chặn cửa. Khách vãng lai vừa lướt vào định đọc bài review thấy báo "Yêu cầu quyền Admin" thì họ chạy sang web đối thủ mua hàng luôn mất! 😂
Hành động Lấy danh sách Blog là hành động Public. Phải mở toang cửa ra!
Anh em sửa lại file routers/blog.js cho gọn gàng:
const router = require('express').Router();
const ctrls = require('../controllers/blog');
const { verifyAccessToken, isAdmin } = require('../middlewares/verifyToken');
// POST & PUT: Thêm và Sửa bài viết thì CHỈ ADMIN mới được làm
router.post('/blogs', [verifyAccessToken, isAdmin], ctrls.createBlog);
router.put('/blogs/:bid', [verifyAccessToken, isAdmin], ctrls.updateBlog);
// 💡 GET: Xem danh sách bài viết -> PUBLIC hoàn toàn (Tháo bảo vệ ra!)
router.get('/blogs', ctrls.getAllBlogs);
module.exports = router;
Lời kết
Test thử thôi! Mở Postman, chọn GET và trỏ thẳng vào http://localhost:5000/api/blog/blogs (không gài Token gì sất). Data trả về một mảng chứa bài viết là ngon lành cành đào.
Danh sách bài viết đã có mặt trên trang chủ. Bước tiếp theo, độc giả thấy tiêu đề hấp dẫn quá, họ sẽ click vào bài viết đó để xem chi tiết.
Và đó chính là sân khấu của Lession 34: Get Blogs By ID.
All rights reserved