Node.js中如何使用Objection.js与express-validator验证对象数组
实现方案
你可以通过「express-validator 做请求层前置校验 + Objection.js 做模型层兜底校验」的方式实现需求,两层校验共用一套规则配置,维护成本低。
1. 先定义统一的配置校验规则
把所有配置项的校验规则提前声明,后续新增配置只需要修改这个映射表即可:
// 可单独抽成配置文件维护 const SETTING_VALIDATION_RULES = { maxImageSize: { min: 1, max: 2048, message: '图片最大尺寸需为1-2048之间的整数' }, maxFileSize: { min: 1, max: 10240, message: '文件最大尺寸需为1-10240之间的整数' }, searchResultsLimit: { min: 1, max: 20, message: '搜索结果限制需为1-20之间的整数' } };
2. express-validator 校验实现
在路由层加校验中间件,提前拦截非法请求:
const { body, validationResult } = require('express-validator'); const settingsValidateMiddleware = [ // 校验settings是不为空的数组 body('settings').isArray({ min: 1 }).withMessage('配置参数必须为非空数组'), // 遍历数组校验每个配置项 body('settings').custom((settings) => { for (const item of settings) { // 校验配置项结构合法性 if (!item.key || typeof item.value === 'undefined') { throw new Error('所有配置项必须包含key、value字段'); } // 校验key是否属于支持的配置项 const rule = SETTING_VALIDATION_RULES[item.key]; if (!rule) { throw new Error(`不支持的配置项:${item.key}`); } // 校验value取值范围 const numVal = Number(item.value); if (isNaN(numVal)) { throw new Error(`${item.key}的取值必须为数字`); } if (numVal < rule.min || numVal > rule.max) { throw new Error(rule.message); } } return true; }) ]; // 路由中使用中间件 app.post('/save-settings', settingsValidateMiddleware, (req, res) => { // 处理校验错误 const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).json({ errors: errors.array() }); } // 校验通过,执行后续存库逻辑 });
3. Objection.js 模型层兜底校验(可选)
如果要避免其他业务逻辑绕过express层直接写入数据库,可以在模型钩子中加校验作为兜底:
const { Model } = require('objection'); // 复用上面定义的规则映射表 const { SETTING_VALIDATION_RULES } = require('./your-config-path'); class Setting extends Model { static get tableName() { return 'settings'; } // 插入前校验 $beforeInsert(context) { super.$beforeInsert(context); this._validateSetting(); } // 更新前校验 $beforeUpdate(opt, context) { super.$beforeUpdate(opt, context); this._validateSetting(); } // 公共校验方法 _validateSetting() { const rule = SETTING_VALIDATION_RULES[this.key]; if (!rule) { throw new Error(`不支持的配置项:${this.key}`); } const numVal = Number(this.value); if (isNaN(numVal) || numVal < rule.min || numVal > rule.max) { throw new Error(rule.message); } } }
内容的提问来源于stack exchange,提问作者porone
相关产品推荐
相关产品推荐

