参数校验:使用joi

在编写api的时候通常都需要对参数进行校验,包括:

  • 参数的类型、必填等;
  • 字符串,是否可以为空、该符合什么规则等;
  • 数字,最大值最小值是什么等等等等。

Joi 是 hapijs 自带的数据校验模块,他已经高度封装常用的校验功能。

安装及使用:

npm install joi --save
import Joi from 'joi'

基础使用

使用joi进行校验,首先要定义它的校验规则,也叫schema。

const schema = Joi.string()

上面就定义了一个校验字符串类型的规则,这个schema会有一个 validate方法,传入需要校验的值:

const result = schema.validate('1')
console.log(result)
// 此时result为 { value: '1' }

validate方法会返回一个对象,如果验证通过,就只会返回value属性,如果验证错误,就还有一个error对象,其中error对象的message描述了失败原因:

const schema = Joi.string()
const result = schema.validate(1)
console.log(result)
// result:
{
  value: 1,
  error: [Error [ValidationError]: "value" must be a string] {
    _original: 1,
    details: [ [Object] ]
  }
}

console.log(result.error.message)
// "value" must be a string

常见schema

  • 字符串、支持空字符串、必填(不能为undefined)
Joi.string().allow('').required()
  • 数字、最小值18、最大值35
Joi.number().min(18).max(35)
  • 数组、长度为3、子元素为字符串、
Joi.array().items(Joi.string()).length(3)
  • 对象、只有p1属性且为字符串
Joi.object({
	p1: Joi.string()
})
  • 函数
Joi.func()
  • 日期
Joi.date()
  • 任意
Joi.any()
  • 正则regex
Joi.string().pattern(/\d/ig)
  • 为空 undefined
Joi.empty()
  • 列举可选值,用valid;age只能取14, 16, 18 中的其一
  • a字段的校验规则要根据b字段的规则确定;(疑问❓:age为数组的话,childAge为数组值中一个❓)
  • 指向其他属性用ref、ancestor往上层对象中查找,找不到就验证失败
const schema = Joi.object({
	age: Joi.number().valid(14, 16, 18),
	childAge: Joi.number().valid(Joi.in('age')),
	childAgeBack: Joi.ref('childAge'),
	childAgeBack1: Joi.ref('childAge', {ancestor: 2}),
})
  • with、without、xor
  • with: 全选。 表示当设置的属性有一个出现了,其他也必须出现,上面的例子设置了a、b属性,需要同时存在或者同时不存在。
  • without: 二者择其一。第一个参数设置条件字段,第二个参数为字段数组,表示第一个参数字段存在的话,第二个参数数组里面的字段都不能存在。上面的例子就是当a字段出现时,b字段就不能存在。
  • xor: 一个或多个。表示设置的参数需要任何一个或多个存在。
const schema = Joi.object({
  a: Joi.any(),
  b: Joi.any()
}).with('a', 'b');

const schema = Joi.object({
  a: Joi.any(),
  b: Joi.any()
}).without('a', ['b']);

const schema = Joi.object({
  a: Joi.any(),
  b: Joi.any()
}).xor('a', 'b');
  • when: 相当于条件判断,第一个参数传递属性名,is相当于if,then后面就是is为真的时候的校验条件。【mode字段只允许传入’email’和’phone’,当mode字段为’email’的时候,address字段就会进行email校验(joi自带的字符串邮箱校验)】
const schema = Joi.object({
  mode: Joi.string().allow('email', 'phone').required(),
  address: Joi.string().when('mode', { is: 'email', then: Joi.string().email() }).required()
});

特殊情况

  1. Joi.string()默认情况不支持空字符串
  2. required()必须放在最后,因为返回值为undefined
  3. 如果没有required(),可以不填值,填了就要遵循规则
  4. 对象schema中,默认不能传入指定外的属性。如果需要允许其他属性的出现,需要在跟上一个unknown方法。
const { error } = schema.validate({
  name: 'chaorenya'
}).unknown() // 允许出现其他字段
  1. Joi.number()校验数字类型、如果字符串可以转换convert为数字,那么默认也会pass。
  2. Joi.number()默认只支持js的safe范围(Number.MIN_SAFE_INTEGER & Number.MAX_SAFE_INTEGER))的数值;非safe范围需要指明:Joi.number().unsafe()

demos


// demo1
  if ((!req.body.keyList || !req.body.keyList.length) && !req.body.hasFilter) {
    return new req.Exception(`keyList / hasFilter ${req.ReturnMessages.INVALID}`)
  }

// joi ed
const schema = Joi.object({
    keyList: Joi.when('hasFilter', { is: Joi.not(true), then: Joi.array().min(1).required() }),
    hasFilter: Joi.boolean()
  })

// demo2
 if (!['FAT', 'FWS'].includes(ENV)) {
    return new req.Exception('env INVALID')
  }

// joi ed
const schema = Joi.object({  
	env:Joi.string().valid('FAT', 'FWS').insensitive().required()
  })
// 或者可以转换为大写再比较,Joi.string().uppercase().valid().required()  

参考

官网API文档

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
nodejs 中的 joi 是一个数据验证库,它可以用于验证请求参数、表单数据等。使用 joi 可以方便地定义验证规则,并且可以自动进行验证,如果验证失败,joi 会返回详细的错误信息。 下面是一个使用 joi 进行参数验证的示例: ```javascript const Joi = require('joi'); const schema = Joi.object({ username: Joi.string().alphanum().min(3).max(30).required(), password: Joi.string().pattern(new RegExp('^[a-zA-Z0-9]{3,30}$')), repeat_password: Joi.ref('password'), 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'] } }) }).with('username', 'password').xor('password', 'access_token').with('password', 'repeat_password'); const result = schema.validate({ username: 'abc', birth_year: 1994 }); console.log(result); ``` 在上面的示例中,我们定义了一个包含多个字段的对象,并使用 joi 定义了每个字段的验证规则。例如,我们要求 username 字段必须是一个长度在 3 到 30 之间的字母数字字符串,而 password 字段必须是一个长度在 3 到 30 之间的字母数字字符串,并且必须与 repeat_password 字段相同。 当我们调用 `schema.validate` 方法时,joi 会自动验证传入的对象是否符合定义的规则,并返回一个包含验证结果的对象。如果验证成功,该对象的 `error` 属性为 `null`,否则为一个包含详细错误信息的对象。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值