You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改Express.js自定义验证中间件以支持验证规则链式调用

实现思路

原来的代码无法支持链式调用的核心原因是:每个验证方法(minLength、maxLength)直接返回了Express中间件函数,导致后续无法继续调用同实例的其他方法。要实现链式调用需要调整为以下逻辑:

  • 每个验证方法执行后返回当前Body实例本身,支持后续链式调用其他验证方法
  • 内部维护一个验证规则队列,所有链式添加的规则都会存入这个队列
  • 最终将整个Body实例包装为标准Express中间件,执行时依次运行队列中所有验证规则
修改后的完整代码

validator.js 调整后代码

/* validator.js */
const createBodyInstance = (check_this) => new Body(check_this)
const Body = function(check_this) {
    // 内部存储所有验证规则
    this.validationQueue = []

    this.minLength = (length) => {
        // 把验证规则推入队列
        this.validationQueue.push((req, res, next) => {
            if(req.body[check_this] && req.body[check_this].length < length) {
                // 此处可自定义验证失败逻辑,比如返回错误响应
                return res.status(400).json({ error: `${check_this}长度不能小于${length}位` })
            }
            next()
        })
        // 返回当前实例,支持链式调用
        return this
    }

    this.maxLength = (length) => {
        this.validationQueue.push((req, res, next) => {
            if(req.body[check_this] && req.body[check_this].length > length) {
                return res.status(400).json({ error: `${check_this}长度不能大于${length}位` })
            }
            next()
        })
        return this
    }

    // 执行所有验证规则的核心方法
    this.runValidations = (req, res, next) => {
        let currentIndex = 0
        const runNextValidation = () => {
            if(currentIndex >= this.validationQueue.length) return next()
            this.validationQueue[currentIndex++](req, res, runNextValidation)
        }
        runNextValidation()
    }
}

// 导出包装后的body方法,让实例可以直接作为中间件被Express调用
module.exports = { 
    body: (...args) => {
        const instance = createBodyInstance(...args)
        return (req, res, next) => instance.runValidations(req, res, next)
    }
}

router.js 调用方式(和你期望的完全一致)

/* router.js */
const { body } = require("./validator")
router.post("/change-password", [
    body("password").minLength(6).maxLength(8)
], function(req, res) {
    /* other code */
})
扩展说明

如果需要新增其他验证规则(比如邮箱格式验证、数字范围验证),只需要按照minLength的写法:往validationQueue推入对应的验证逻辑,然后返回this即可,不需要调整整体结构。

内容的提问来源于stack exchange,提问作者May Myat Thuzar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 08:36:02