Joi官网

1、定义 schema 时 Joi.object.keys() 和 Joi.object() 有什么区别?

并无区别,官网给了三种定义实现的方式。如下:

// 使用 { } 来定义
const schema = {
    a: Joi.string(),
    b: Joi.number()
};

// 使用 Joi.object()
const schema = Joi.object({
    a: Joi.string(),
    b: Joi.number()
});

// 使用 Joi.object.keys()
const schema = Joi.object().keys({
    a: Joi.string(),
    b: Joi.number()
})

三种方式实现效果一样,但是在使用时会稍有不同。
– 当使用 {} 时,只是定义了一个普通的js对象,它不是一个完整的 schema 对象。你可以将它传递给验证方法,但不能调用对象的validate()方法,即类似这种 object.validate()的操作是不可以的,因为它只是一个普通的js对象。此外,每次将{}对象传递给validate()方法,都将对每个验证执行一个昂贵的模式编译操作。

  • 当使用 Joi.object() 时,相对于使用 {} ,这是正经的schema 对象,它会在第一次编译,所以你可以多次将它传递给validate()方法,不会增加开销。另外,你还可以设置 options 来验证。

  • 当使用 Joi.object.keys() 时,其实和使用 Joi.object() 是类似的,但是当你想添加更多的键(例如多次调用keys())时,使用joi.object().keys([schema])会更有用。如果只添加一组键,则可以跳过keys()方法,直接使用object()。有些人喜欢用keys()来使代码看起来更加精确(其实这只是一种编程风格)。

2. Joi.validate(value, schema, [options], [callback])中的 options 取值有哪些?

  • abortEarly: 设置true,可以在检测到第一个错误时立即返回,默认false(检查全部)。推荐设置true
  • convert:设置true,可以尝试将值转换为所需的类型(例如,将字符串转换为数字)。默认为true。推荐采用默认
  • allowunknown: 设置true,则允许对象包含被忽略的未知键。默认为false。推荐设置true
  • skipfunctions:如果为true,则忽略具有函数值的未知键。默认为false。推荐采用默认
  • stripunknown: 如果为true,从对象和数组中删除未知的元素。默认为false。也可以特殊的设置成 { objects: true , arrays: true }的形式,可以对象和数组分别处理。推荐采用默认
  • presence: 设置默认的可选需求。支持的模式:’optional’,’required’,和’forbidden’。默认为’optional’。推荐采用默认
  • escapehtml: 当为true时,出于安全目的,错误消息模板将特殊字符转义为html实体。默认为false。推荐采用默认
  • nodefaults:如果为true,则不应用默认值。默认为false。推荐采用默认
  • context: 提供一个外部数据集用于引用。只能设置为外部选项来验证()而不使用any.options()。使用方法:
const schema = Joi.object().keys({
    a: Joi.ref('b.c'),
    b: {
        c: Joi.any()
    },
    c: Joi.ref('$x')
});

Joi.validate({ a: 5, b: { c: 5 } }, schema, { context: { x: 5 } }, (err, value) => {});

3、一些例子

let testData = { xxx };

let paramSchema = Joi.object().keys({
    username: Joi.string().alphanum().min(3).max(30).required(), //alphanum() 仅包含a-z,A-Z和0-9。 string().min() 字符串最小长度
    password: Joi.string().regex(/^[a-zA-Z0-9]{3,30}$/),
    access_token: [Joi.string(), Joi.number()], //字符串或数字
    birthyear: Joi.number().integer().min(1900).max(2013), //integer() 整数 number().min() 最小值
    email: Joi.string().email(), //string().emial() 字符串值时有效电子邮件地址
    website: Joi.string().uri({
        scheme: [
            'git',
            /git\+https?/
        ]
    }),//
    search: Joi.string().allow(''),//允许空值
    type: Joi.string().valid('disabled', 'normal', 'all').default('all'), //valid() 允许的值
    startTime: Joi.date().min('1-1-1974').max('now'), //日期
    endTime: Joi.when( Joi.ref('startTime'), { is: Joi.date().required(), then: Joi.date().max('1-1-2100') } ), //Joi.ref()引用 when(a,{is: , then: , otherwise: })
    page: Joi.number().integer().min(1).default(1),
    pageSize: Joi.number().integer().default(8),
    deleteWhenLtTen: Joi.number().integer().max(10).strip(),
    arraySelect: Joi.array().items(Joi.string().label('My string').required(), Joi.number().required()), //数组schema
});

let { error, value } = Joi.validate(testData, paramSchema, { allowUnknown: true, abortEarly: true });
if (error) {
    throw error;
}
query = value;
Scroll to Top