[Series Thực Chiến E-commerce] Bài 26: Xây "Trạm Content" hút traffic - Tạo Model & API Danh mục Blog
Chào bố đời! Tốc độ ra bài của anh em mình dạo này đúng là "cháy" khét lẹt.
Chúng ta đã giải quyết cực kỳ êm thấm cái lõi của một trang thương mại điện tử là Sản phẩm (Product) và Danh mục sản phẩm (Product Category). Tuy nhiên, làm hệ thống bán lẻ thực chiến thì không thể chỉ bày mỗi hàng ra bán. Để "kéo traffic" tự nhiên, tăng SEO và tăng độ uy tín với khách hàng, một hệ thống e-commerce luôn cần một không gian để làm Content Marketing: Hệ thống Bài viết (Blog).
Ví dụ, bán mỹ phẩm thì phải có blog hướng dẫn skincare, bán đồ công nghệ thì phải có bài review đập hộp. Và tất nhiên, Blog thì cũng cần được phân loại gọn gàng. Hôm nay, chúng ta sẽ bắt tay vào khởi tạo Danh mục Blog (Blog Categories) nhé!
1. Tại sao không dùng chung Model với ProductCategory?
Nhìn vào đoạn code models/blogCategory.js bố đời vừa viết, nhiều anh em newbie sẽ thắc mắc: "Ô, cái Schema này giống hệt ProductCategory (cũng có mỗi trường title), sao không xài chung một Model cho tiện mà phải tách ra làm gì cho tốn file?".
Đây là một tư duy phân tách Domain rất hay!
Trong thực tế, vòng đời của "Danh mục Sản phẩm" và "Danh mục Blog" hoàn toàn khác nhau. Danh mục sản phẩm có thể sau này cần thêm icon, banner quảng cáo, hoặc phân cấp cha - con phức tạp. Còn danh mục blog thường chỉ cần dạng text đơn giản. Việc tách riêng 2 collection ProductCategory và BlogCategory ngay từ đầu giúp cơ sở dữ liệu (Database) không bị phình to lộn xộn, dễ dàng mở rộng (scale) và maintain về sau.
Mã nguồn Model của bố đời đã rất chuẩn, mình chỉ bưng nguyên vào file thôi:
const mongoose = require('mongoose');
var blogCategorySchema = new mongoose.Schema({
title: {
type: String,
required: true,
unique: true, // Tránh tạo 2 danh mục blog trùng tên
index: true,
},
}, {
timestamps: true
});
module.exports = mongoose.model('BlogCategory', blogCategorySchema); // Viết hoa chữ cái đầu cho chuẩn convention nhé
2. Não bộ xử lý (Controller)
Logic Thêm mới Danh mục Blog không khác gì Thêm Danh mục Sản phẩm. Bố đời vẫn giữ vững phong độ với việc bắt lỗi body rỗng và trả về HTTP Status 201 Created cực kỳ chuẩn RESTful.
Anh em đưa đoạn này vào file controllers/blogCategory.js:
const BlogCategory = require('../models/blogCategory');
const asyncHandler = require('express-async-handler');
// Hàm tạo danh mục blog mới
const createCategory = asyncHandler(async (req, res) => {
// Validate đầu vào
if (!req.body.title) {
return res.status(400).json({
success: false,
message: 'Title is required - Vui lòng nhập tên danh mục Blog'
});
}
// Insert vào Database
const response = await BlogCategory.create(req.body);
// Trả về data
return res.status(201).json({
success: true,
createdCategory: response
});
});
module.exports = {
createCategory,
}
3. "Trám" nốt phần Router đang bỏ ngỏ
Trong tin nhắn vừa nãy, mục routers/blogCategories.js bố đời để trống chưa viết code kìa! Chắc do mải gõ phím quá nên quên đúng không?
Cũng giống như danh mục sản phẩm, việc tạo ra một cái ngách mới cho Blog là quyền lực của Admin. Mình sẽ tự tay múa luôn đoạn Router này giúp bố đời nhé:
Anh em tạo file routers/blogCategory.js và cắm hai anh bảo vệ vào:
const router = require('express').Router();
const ctrls = require('../controllers/blogCategory');
const { verifyAccessToken, isAdmin } = require('../middlewares/verifyToken');
// Tuyến đường POST yêu cầu: Đăng nhập + Quyền Admin
router.post('/', [verifyAccessToken, isAdmin], ctrls.createCategory);
module.exports = router;
Nhớ móc nối vào hệ thống: Anh em mở file trạm điều phối trung tâm routers/index.js và thêm luồng cho Blog Category nhé:
const blogCategoryRouter = require('./blogCategory');
// ...
app.use('/api/blogcategory', blogCategoryRouter);
Lời kết
Bật Postman lên, nhét Token Admin vào, chĩa đường dẫn POST vào/api/blogcategory/ kèm theo một cục JSON {"title": "Kiến thức công nghệ"}. Trả về status 201 xanh lè là kho Content của chúng ta đã có nền móng đầu tiên rồi.
Đã có hàm Thêm (Create) thì bắt buộc phải có hàm lấy danh sách (Read) để Frontend còn hiển thị ra giao diện cho người đọc chọn chuyên mục.
All rights reserved