如何使用 Joi 验证对象数组?

Posted

技术标签:

【中文标题】如何使用 Joi 验证对象数组?【英文标题】:How to validate array of objects using Joi? 【发布时间】:2016-10-11 04:47:51 【问题描述】:

我将一组对象发送到后端,其中每个对象都包含一个服务名称。 结构如下图

["serviceName":"service1",
"serviceName":"service2",..]

当我在后端获取数组时,我想验证数组中的每个对象都具有 serviceName 属性。

我已经编写了以下代码,但即使我传递了有效的数组,我也会收到验证错误。

var Joi = require('joi');
var service = Joi.object().keys(
  serviceName: Joi.string().required()
);

var services = Joi.array().ordered(service);

var test = Joi.validate([serviceName:'service1',serviceName:'service2'],services)

对于上述代码,我总是收到带有消息的验证错误

"value" at position 1 fails because array must contain at most 1 items

【问题讨论】:

【参考方案1】:

ordered 替换为 items 即可。

let Joi = require('joi')
let service = Joi.object().keys(
  serviceName: Joi.string().required(),
)

let services = Joi.array().items(service)

let test = Joi.validate(
  [ serviceName: 'service1' ,  serviceName: 'service2' ],
  services,
)

供参考click here

【讨论】:

正是我需要的。谢谢! Joi.validate 在版本 16 中已弃用。为了保持相同的解决方案,您现在只需使用 Joi.validate([], services) 代替 services.validate([], callback)services.validateAsync([]) 它将通过空数组service = []的验证,使用Joi.array().min(1).items(service)来确保服务包含一些值。 事实上 .key() 函数现在也不需要了,这也可以。让 service = Joi.object( serviceName: Joi.string().required(), );【参考方案2】:

一个基本/更清晰的例子如下。 要验证这样的 JSON 请求:

   
    "data": [
            
        "keyword":"test",
        "country_code":"de",
        "language":"de",
        "depth":1
            
        ]
    

这是 Joi 验证:

 seoPostBody: 
    body: 
      data: Joi.array()
        .items(
          keyword: Joi.string()
            .required(),
          country_code: Joi.string()
            .required(),
          language: Joi.string()
            .required(),
          depth: Joi.number()
            .required(),
        ),
    ,
  ;

这是我在 NodeJs 中所做的,可能需要对其他平台进行一些细微的更改

【讨论】:

谢谢,你的例子在我的用例中帮助了我; json json "tags": [ "61b394ead5a3863d6a41fedf", "61b292f38561f0c5550ca78c" ] 验证js tags: Joi.array().max(4).min(1).items(Joi.string()) 【参考方案3】:

只是想让它更清楚。我目前正在使用“@hapi/joi:16.1.7”。

假设您希望您的架构验证此对象数组。

const example = [
   
      "foo": "bar",
      "num": 1,
      "is_active": true,
   
];

那么架构的规则应该是:

var validator = require('@hapi/joi');

const rules = validator.array().items(
    validator.object(
        foo: validator.string().required(),
        num: validator.number().required(),
        is_active: validator.boolean().required(),
    ),
);

const  error  = rules.validate(example);

【讨论】:

【参考方案4】:
const test = 
body: Joi.array()
    .items(
        x: Joi.string().required(),
        y: Joi.string().required(),
        z: Joi.string().required(),
        date: Joi.string().required(),
    )

;

【讨论】:

欢迎来到 Stack Overflow。 Stack Overflow 上不鼓励仅使用代码的答案,因为它们没有解释它是如何解决问题的。请编辑您的答案以解释此代码的作用以及它如何改进该问题已有的现有投票答案,以便对其他有类似问题的用户有用。【参考方案5】:

对于 Joi,您可以使用下面这对我来说工作正常,这将验证该数组必须至少在对象上具有 key serviceName-

const Joi = require('joi');
const itemsArray = Joi.array().items(
            Joi.object(
                serviceName: Joi.string().required(),
            )
        ).min(1).required();

        const itemSchema = Joi.array().items(itemsArray).when('checkout_type', 
            is: 'guest',
            then: Joi.array().required(),
        ).required();

let schema = Joi.object().keys(
        items: Joi.alternatives().try(itemsArray, itemSchema).required(),
    );

【讨论】:

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

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

Joi 对象验证:如何验证具有未知键名的值?

JOI:允许数组中的空值

如何使用 dto 验证 nestjs 中的对象数组

如何让我的服务器端 Joi 验证与 redux-form 一起正常工作?

Joi 验证仅返回一条错误消息