【问题标题】:express validator: separating logicexpress 验证器:分离逻辑
【发布时间】:2021-03-17 20:51:53
【问题描述】:

这个问题更多是关于代码组织而不是错误/错误问题。

我正在处理请求正文验证,json 的结构如下:

  {
      "title": "Beetlejuice",
      "year": "1988",
      "runtime": "92",
      "genres": [
          "Comedy",
          "Fantasy"
      ],
      "director": "Tim Burton",
      "actors": "Alec Baldwin, Geena Davis, Annie McEnroe, Maurice Page",
      "plot": "A couple of recently deceased ghosts contract the services of a \"bio-exorcist\" in order to remove the obnoxious new owners of their house.",
      "posterUrl": "https://images-na.ssl-images-amazon.com/images/M/MV5BMTUwODE3MDE0MV5BMl5BanBnXkFtZTgwNTk1MjI4MzE@._V1_SX300.jpg"
  }

虽然 json 不大,但在简单的 POST 请求上验证仍然很大:

router.post('/api/movies/',
    body('genres')
        .isArray()
        .withMessage('Property genres should be array of string.').bail()
        .custom(validateGenres).bail(),
    body('title')
        .not().isEmpty()
        .withMessage('Property title is required.').bail()
        .isString()
        .withMessage('Property title must be string.').bail()
        .isLength({ max: 255 })
        .withMessage('Property title must have maximum 255 characters.').bail(),
    body('year')
        .not().isEmpty()
        .withMessage('Property year is required.').bail()
        .isNumeric()
        .withMessage('Property year must be number.').bail(),
    body('runtime')
        .not().isEmpty()
        .withMessage('Property runtime is required.').bail()
        .isNumeric()
        .withMessage('Property runtime must be number.').bail(),
    body('director')
        .not().isEmpty()
        .withMessage('Property director is required.').bail()
        .isString()
        .withMessage('Property director must be string.').bail()
        .isLength({ max: 255 })
        .withMessage('Property director must have maximum 255 characters.').bail(),
    body('actors')
        .isString()
        .withMessage('Property actors  must be string.').bail(),
    body('plot')
        .isString()
        .withMessage('Property plot must be string.').bail(),
    body('posterUrl')
        .isString()
        .withMessage('Property plot must be string.').bail(),
    (req, res) => {

        const errors = validationResult(req);
        if (!errors.isEmpty()) {
            return res.status(400).send(errors.array())
        }

        const movieCreated = movie.create(req.body);
        
        return res.status(201).json(movieCreated);
    }) 

这里的问题是:这种大型验证是否被视为不好的做法?如果是,我应该创建一个验证这个特定 json 的中间件,还是有什么可能的架构解决方案来解决这种重构问题?

【问题讨论】:

    标签: javascript node.js express express-validator


    【解决方案1】:

    这里的好习惯是您正在验证输入✅

    您当前方法的缺点是很难长期维持 ❌

    您可以采用中间件方式,并为您需要验证的每个路由/主体创建多个中间件。它可以工作,但是随着时间的推移,工作量和维护负担会增加。

    您可以采用的一种方法是创建输入的预期架构(例如,描述预期字段和值的模型定义),并使用验证器根据您创建的架构检查当前输入。

    对于 Node.js,我们有多种工具,例如:AJVJOIYUP

    使用 JOI 示例,您可以通过以下方式替换您的验证流程:

    // ./validation/post-create-user-schema.js
    const Joi = require('joi');
    
    const postCreateUserSchema = Joi.object({
      username: Joi.string().alphanum().min(3).max(30).required(),
      password: Joi.string().pattern(new RegExp("^[a-zA-Z0-9]{3,30}$")).required(),
      repeat_password: Joi.ref("password").required(),
      access_token: [Joi.string(), Joi.number()],
      birth_year: Joi.number().integer().min(1900).max(2013),
      email: Joi.string().email({
        minDomainSegments: 2,
        tlds: { allow: ["com", "net"] },
      }),
    });
    
    module.exports = { postCreateUserSchema };
    
    
    
    // ./routes.js
    const { postCreateUserSchema } = require('./validation/post-create-user-schema.js')
    
    router.post('/api/users/', (req, res) => {
      try {
        let json = JSON.parse(req.body);
        postCreateUserSchema.validate(json);
      } catch (err) {
        // -> { value: {}, error: '"username" is required' }
        console.error(err);
        return res.status(400).send({ ok: false, message: err.error });
      }
    
      // ... route code here
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多