在使用restify实现webapi时常常会遇到获取和验证请求参数的问题,与.NET、JAVA等编程语言有确定类型不同,JavaScript这类脚本语言输入参数并没有明确的类型,如果获取失败会返回undefined,当输入参数有多个字段时,单纯依靠传统判断方式不仅麻烦而且容易遗漏不容易维护,故而将验证流程统一成为可复用方法是比较好的选择。

首先需要定义输入参数的范围,即输入参数的格式。一般情况下,我们采用application/json格式。以用户注册为例,以下罗列一些用户注册时的参数:

const defaultParams = {
  username: {
    type: 'string',
    required: true,
  }, // 用户名
  password: {
    type: 'string', allowNull: true,
  }, // 密码MD5格式
  mobile: { type: 'string', allowNull: true }, // 手机号
  email: { type: 'string', allowNull: true }, // 邮箱
  gender: {
    type: 'int',
    allowNull: true,
    validate: src => [0, 1, 2].indexOf(src) >= 0,
  }, // 性别(0-未知,1-男,2-女)
  birthday: { type: 'datetime', allowNull: true }, // 生日
  zipcode: { type: 'string', allowNull: true }, // 邮编
  nickname: { type: 'string', allowNull: true } // 昵称
};

其中type字段类型,allowNull是否允许字段缺失,required是否必要,validate验证条件。下面就要从post数据体内获取需要的数据。

const getParams = (params, defaultParams) => {
  const result = {};
  const keys = Object.keys(defaultParams);
  for (let i = 0, len = keys.length; i < len; i += 1) {
    result[keys[i]] = typeof params[keys[i]] === 'string' ? params[keys[i]].trim() : params[keys[i]];
  }
  return result;
};

获取数据后就可以进行验证了,我们可以对于不同的数据类型进行统一的处理。

const validate = {
  string: src => (typeof src === 'string'),
  int: src => (typeof src === 'number' && src % 1 === 0),
  float: src => (typeof src === 'number'),
  datetime: (src) => {
    const time = moment(src, dateFormat);
    const result = validate.string(src)
      && time.isValid()
      && time.format(dateFormat).split(' ').join('') === src.split(' ').join('');
    return result;
  },
  mobile: (src) => {
    const reg = /^1[3|4|5|7|8][0-9]{9}$/;
    const result = validate.string(src) && reg.test(src);
    return result;
  },
  email: src => (validate.string(src) && validator.isEmail(src)),
};
 


const validateParams = (params, paramsTemplate) => {
  let errCode = rtCode.paramsErr;
  const keys = Object.keys(paramsTemplate);
  for (let i = 0, len = keys.length; i < len; i += 1) {
    if (paramsTemplate[keys[i]].required) {
      if (params[keys[i]] === undefined || params[keys[i]] === null) {
        return { errCode: rtCode.dataLost, msg: `${keys[i]} is required.` };
      }
      if (params[keys[i]] === '') {
        errCode = paramsTemplate[keys[i]].errCode || rtCode.paramsErr;
        return { errCode, msg: `${keys[i]} can't be empty string.` };
      }
    }
    if (params[keys[i]] !== undefined) {
      if (
        !(paramsTemplate[keys[i]].allowNull && params[keys[i]] === null)
        && !validate[paramsTemplate[keys[i]].type](params[keys[i]])
      ) {
        return { errCode, msg: `${keys[i]} must is ${paramsTemplate[keys[i]].type}.` };
      }
      if (
        !(paramsTemplate[keys[i]].allowNull && params[keys[i]] === null)
        && paramsTemplate[keys[i]].validate
        && !paramsTemplate[keys[i]].validate(params[keys[i]])
      ) {
        errCode = paramsTemplate[keys[i]].errCode || rtCode.paramsErr;
        return { errCode, msg: `${keys[i]} is not match.` };
      }
    }
  }
  return { errCode: rtCode.success };
};

好了,以上就完成所有的验证步骤了。

原文来自:https://my.oschina.net/mutoushirana/blog/1842738

本文地址:https://www.linuxprobe.com/nodejs-resify.html编辑:吴向平,审核员:逄增宝