Hapi/Joi 使用嵌套对象验证

Hapi/Joi validation with nested object

我在其中一条路线上进行了以下验证:

payload: {
    keywordGroups: Joi.array().items(Joi.object().keys({
        language: Joi.string().required(),
        containsAny: Joi.array().items(Joi.string()).default([]).when('containsAll', { is: [], then: Joi.required() }),
        containsAll: Joi.array().items(Joi.string()).default([]).when('containsAny', { is: [], then: Joi.required() }),
        notContainsAll: Joi.array().items(Joi.string()).default([]),
        notContainsAny: Joi.array().items(Joi.string()).default([])
    })).required(),
}

我正在努力使 containsAnycontainsAll 必须包含至少一个字符串。如果 containsAny 为空,则 containsAll 应该至少有一项。如果 containsAll 为空,则 containsAny 至少应包含一项。

但似乎 Joi.when 在涉及到对象数组时并没有真正起作用。

您需要使用 Joi.alternatives() otherwise you will create a circular dependency as described in this issue

when() 中的 is 条件中,您需要指定一个 Joi 类型,而不仅仅是一个空数组。这个例子有效:

import * as Joi from 'joi';

var arraySchema = Joi.array().items(Joi.object().keys({
    first: Joi.array().items(Joi.number()).default([])
        .when('second', {is: Joi.array().length(0), then: Joi.array().items(Joi.number()).required().min(1)}),
    second: Joi.array().items(Joi.number()).default([])
}));

var altArraySchema = Joi.array().items(Joi.object().keys({
    first: Joi.array().items(Joi.number()).default([]),
    second: Joi.array().items(Joi.number()).default([])
        .when('first', {is: Joi.array().length(0), then: Joi.array().items(Joi.number()).required().min(1)}),
}));

var obj = [
    {
        first: [],
        second: []
    }
];

var finalSchema = Joi.alternatives(arraySchema, altArraySchema);

var result = Joi.validate(obj, finalSchema);

console.log(JSON.stringify(result, null, 2));

变量 obj 将无法通过验证,因为 firstsecond 都是空的。使它们中的任何一个非空将通过验证检查。