架构设计
- 模块化路由:将不同层级的路由分开定义,便于维护和管理。例如:
const express = require('express');
const categoryRouter = express.Router();
const subcategoryRouter = express.Router();
const productRouter = express.Router();
categoryRouter.param('categoryId', (req, res, next, categoryId) => {
// 这里可以对categoryId进行验证等预处理
req.categoryId = categoryId;
next();
});
subcategoryRouter.param('subcategoryId', (req, res, next, subcategoryId) => {
req.subcategoryId = subcategoryId;
next();
});
productRouter.param('productId', (req, res, next, productId) => {
req.productId = productId;
next();
});
productRouter.get('/', (req, res) => {
// 处理/product/:productId请求
});
subcategoryRouter.use('/product', productRouter);
categoryRouter.use('/subcategory/:subcategoryId', subcategoryRouter);
app.use('/category/:categoryId', categoryRouter);
- 中间件分层:使用中间件对请求进行预处理,如参数验证、日志记录等。
const validateQuery = (req, res, next) => {
const { color, size } = req.query;
if (color && typeof color!=='string') {
return res.status(400).send('Invalid color query parameter');
}
if (size && typeof size!=='string') {
return res.status(400).send('Invalid size query parameter');
}
next();
};
app.get('/category/:categoryId/subcategory/:subcategoryId/product/:productId', validateQuery, (req, res) => {
// 处理请求
});
缓存策略
- 基于参数和查询字符串的缓存:使用一个唯一的键来标识请求,例如将所有参数和查询字符串拼接成一个哈希值。
const nodeCache = require('node-cache');
const myCache = new nodeCache();
const generateCacheKey = (req) => {
const { categoryId, subcategoryId, productId } = req.params;
const { color, size } = req.query;
return `${categoryId}:${subcategoryId}:${productId}:${color}:${size}`;
};
app.get('/category/:categoryId/subcategory/:subcategoryId/product/:productId', validateQuery, (req, res) => {
const cacheKey = generateCacheKey(req);
const cachedData = myCache.get(cacheKey);
if (cachedData) {
return res.send(cachedData);
}
// 处理请求,获取数据
const data = { message: 'Processed data' };
myCache.set(cacheKey, data);
res.send(data);
});
- 缓存失效策略:可以设置缓存的过期时间,或者在数据发生变化时手动清除缓存。
// 设置缓存过期时间为60秒
myCache.set(cacheKey, data, 60);
异步处理
- 使用async/await:确保在处理数据库查询或其他异步操作时,代码保持同步风格,避免回调地狱。
const Product = require('../models/product');
app.get('/category/:categoryId/subcategory/:subcategoryId/product/:productId', validateQuery, async (req, res) => {
const cacheKey = generateCacheKey(req);
const cachedData = myCache.get(cacheKey);
if (cachedData) {
return res.send(cachedData);
}
try {
const product = await Product.findById(req.productId).where('color', req.query.color).where('size', req.query.size);
myCache.set(cacheKey, product);
res.send(product);
} catch (error) {
res.status(500).send('Error fetching product');
}
});
- 并发异步操作:如果有多个异步操作可以并行执行,可以使用
Promise.all
来提高性能。
const Category = require('../models/category');
const Subcategory = require('../models/subcategory');
const Product = require('../models/product');
app.get('/category/:categoryId/subcategory/:subcategoryId/product/:productId', validateQuery, async (req, res) => {
const cacheKey = generateCacheKey(req);
const cachedData = myCache.get(cacheKey);
if (cachedData) {
return res.send(cachedData);
}
try {
const [category, subcategory, product] = await Promise.all([
Category.findById(req.categoryId),
Subcategory.findById(req.subcategoryId),
Product.findById(req.productId).where('color', req.query.color).where('size', req.query.size)
]);
const combinedData = { category, subcategory, product };
myCache.set(cacheKey, combinedData);
res.send(combinedData);
} catch (error) {
res.status(500).send('Error fetching data');
}
});