在使用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 };
};
好了,以上就完成所有的验证步骤了。