数组的Joi验证

Posted

技术标签:

【中文标题】数组的Joi验证【英文标题】:Joi validation of array 【发布时间】:2017-07-28 03:33:28 【问题描述】:

试图验证一个数组在一种情况下有零个或多个字符串,而在另一种情况下它有零个或多个对象,在 Joi 文档中苦苦挣扎:(

validate: 
        headers: Joi.object(
                'content-type': "application/vnd.api+json",
                accept: "application/vnd.api+json"
        ).options( allowUnknown: true ),
        payload : Joi.object().keys(
            data : Joi.object().keys(
                type: Joi.any().allow('BY_TEMPLATE').required(),
                attributes: Joi.object(
                    to : Joi.string().email().required(),
                    templateId : Joi.string().required(),
                    categories : Joi.array().items( //trying to validate here that each element is a string),
                    variables : Joi.array(
                        //also trying to validate here that each element is an Object with one key and value
                    )
                )
            ).required()
        )
    

【问题讨论】:

【参考方案1】:

Joi.array().items() 接受另一个 Joi 模式以用于数组元素。所以字符串数组就这么简单:

Joi.array().items(Joi.string())

对象数组也是如此;只需将对象模式传递给items()

Joi.array().items(Joi.object(
    // Object schema
))

【讨论】:

Joi.array().items(Joi.object( inputA:Joi.string().optional(), inputB:Joi.string().require() )) 在这些架构上inputA 是可选的,并且 inputB 是必需的,但是在发送请求时 inputA 给出了经过验证的错误 inputA 不应为空 @MohammadFaisal 我无法重现该错误。使用该架构,值 [ inputB: 'test' ] 通过验证。仔细检查您的代码。请注意,[ inputA: '', inputB: 'test' ] 确实 not 通过验证——要么传递一个非空字符串,要么不传递任何东西。 (默认情况下,字符串必须至少包含一个字符,如果提供了。 所以不要发送空字符串!)【参考方案2】:
validate: 
        headers: Joi.object(
                'content-type': "application/vnd.api+json",
                accept: "application/vnd.api+json"
        ).options( allowUnknown: true ),
        payload : Joi.object().keys(
            data : Joi.object().keys(
                type: Joi.any().allow('BY_TEMPLATE').required(),
                attributes: Joi.object(
                    to : Joi.string().email().required(),
                    templateId : Joi.string().required(),
                    categories : Joi.array().items(Joi.string()),
                    variables : Joi.array().items(Joi.object().keys().max(1))
                )
            ).required()
        )
    

【讨论】:

【参考方案3】:

Joi.array().items(Joi.string().required(), Joi.number().required());找到它here

【讨论】:

太棒了!谢谢【参考方案4】:

你可以试试这个:

function(data) 
 const Schema = 
   categories: Joi.array().items(Joi.string()),
   variables: Joi.array().items(Joi.object().keys().min(1))
 
 return Joi.validate(data, Schema)

有关更多详细信息,请查看此 repo:https://github.com/raysk4ever/nodejs_withMongoRefArray

【讨论】:

请提供一些解释,以便所有人都能从您的回答中受益。 @Zeina 结账github.com/raysk4ever/nodejs_withMongoRefArray 这对我来说很有效,因为我只是在测试一个解决方案。非常感谢!【参考方案5】:

您也可以尝试这种方式,我已经使用了很长时间并且对我来说工作正常。

如果你的数组是对象数组而不是下面使用:

const Joi = require('joi');

let schema = Joi.object().keys(
            items: Joi.array().items(
                Joi.object(
                    item_id: Joi.number().required(),
                    item_qty: Joi.number().required(),
                    item_type_id: Joi.number().required(),
                    item_qty: Joi.number().required(),
                    base_price: Joi.number().required(),
                    actual_price: Joi.number().required(),
                )
            ).required(),
        );

        let errors = Joi.validate(req.body, schema);

如果你的数组是简单的数组:

let schema = Joi.object().keys(
                items: Joi.array().items(
                Joi.number().required()
            ).min(10).required(),
            );

【讨论】:

谢谢!这帮助我完成了我一直在寻找的东西。【参考方案6】:

如果要验证 Joi 中的字符串数组:

Joi.array().items(Joi.string().valid("item1", "item2", "item3", "item4"))

【讨论】:

【参考方案7】:

当我们有一个使用 Joi 的对象数组时进行验证:

const schema = Joi.array().items(
Joi.object().keys(
  id: Joi.number().required(),
  name: Joi.string().required(),
));

我们可以为数组本身的对象添加验证。

【讨论】:

以上是关于数组的Joi验证的主要内容,如果未能解决你的问题,请参考以下文章

Joi 验证 - 如何根据数组中存在的另一个键来要求或可选字段?

JOI:允许数组中的空值

BZOJ4240有趣的家庭菜园 树状数组+贪心

Joi 验证多个条件

Joi验证忽略嵌套键

JOI 电子邮件验证