首页 关于我们

egg整合数据校验

Word count: 770 / Reading time: 3 min
2018/02/14 Share

egg官方的插件egg-validate依赖了parameter包,其只做了两个处理

Copy Code


1
2
3
4
5
6
7
8
9
10
11
12
13
14
// egg-validate/app.js
app.validator = new Parameter();

// egg-validate/app/extend/context.js
validate(rules, data) {
data = data || this.request.body;
const errors = this.app.validator.validate(rules, data);
if (errors) {
this.throw(422, 'Validation Failed', {
code: 'invalid_param',
errors,
});
}
}

可见其做了两件事:

  • 1、启动时创建了一个实例
  • 2、封装了一个调用方法,和错误的时候自定义了一个http状态,抛出

Copy Code


1
2
3
4
[
{message: 'should not be empty', code: 'invalid', field: 'name'},
{message: 'should be an integer', code: 'invalid', field: 'age'}
]

这里有几个不好的地方:

  • 1、没有暴露自定义parameter校验返回的信息,只能用这些提示。不能满足业务需求
  • 2、封装的validate方法个人感觉不够友好,直接抛出错误
  • 3、parameter的实现比较简单,使用比较方便,但对于自定义要求比较高需求灵活性还不够,例如它在对string校验时,为空的提示语不能自定义,只有配置了format的才可以自定义提示

前两点覆盖的方式重写,但重写了,跟直接引用parameter并没有太大区别。所以建议还是直接用parameter这个插件。用法比较简单,直接拓展context上下文。

Copy Code


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// extend/context.js
const VALIDATOR = Symbol('Application#validator'); // 定义一个全局唯一的属性
var Parameter = require('parameter');

module.exports = {
get validator () {
const that = this
if (!this[VALIDATOR]) {
this[VALIDATOR] = new Parameter({
translate () { // 翻译成多语言
const arg = [...arguments]
return that.__(...arg)
}
})
}
return this[VALIDATOR]
},
validate(rules, data) {
data = data || this.request.body;
const errors = this.validator.validate(rules, data);
console.log(errors)
return errors
}
};

parameter的使用

  • 1、插件提示语是英文的,那需要支持多语言,所幸其暴露了translate的配置项,引入egg-i18n即可

  • 2、定义了一些简写:

  • 'int' => {type: 'int', required: true}
  • 'integer' => {type: 'integer', required: true}
  • 'number' => {type: 'number', required: true}
  • 'date' => {type: 'date', required: true}
  • 'dateTime' => {type: 'dateTime', required: true}
  • 'id' => {type: 'id', required: true}
  • 'boolean' => {type: 'boolean', required: true}
  • 'bool' => {type: 'bool', required: true}
  • 'string' => {type: 'string', required: true, allowEmpty: false}
  • 'email' => {type: 'email', required: true, allowEmpty: false, format: EMAIL_RE}
  • 'password' => {type: 'password', required: true, allowEmpty: false, format: PASSWORD_RE, min: 6}
  • 'object' => {type: 'object', required: true}
  • 'array' => {type: 'array', required: true}
  • [1, 2] => {type: 'enum', values: [1, 2]}
  • /\d+/ => {type: 'string', required: true, allowEmpty: false, format: /\d+/}

  • 3、一个简单的例子:

Copy Code


1
2
3
4
5
6
7
8
9
10
11
12
13
const error = this.ctx.validate({
content: 'string',
difficulty: ['1', '2', '3', '4', '5'],
type: ['1', '2', '3', '4'],
options: {
type: 'array',
itemType: 'object',
required: false,
rule: {
text: {type: 'string', format: /^\S{6,}$/, message: '选项的内容不能少于3个字'}
}
}
})

需要注意一点,ctx.request.body或者ctx.request.query里拿到的只有字符串或者对象,没有数字类型,所以别用int或者integer

CATALOG
  1. 1. parameter的使用