Javascript Joi 替代数组或对象数组

Javascript Joi Alternatives Array or Array of Objects

我对 Joi 备选方案感到困惑。我不知道如何针对要验证的项目调用替代方案。

function validateCourse(course) {
    const objectSchema = {
        id: Joi.number().required(),
        name: Joi.string().min(3).required()
    };

    const arraySchema = Joi.array().items(Joi.object(objectSchema)).required();

    return Joi.alternatives(objectSchema, arraySchema).validate(course);
}

这适用于对象,但不适用于对象数组。

[ 
  {
    "id": 10,
    "name": "XY"
  }, 
  {
    "id": 11,
    "name": "JFK"
  }
]

我不确定是我的数组架构有问题还是我使用了替代方案?

看来它正在工作!然而,与验证对象相比,Joi 在验证数组时返回的失效消息是模糊的。

validating object : "name" length must be at least 3 characters long
validating array : "value" must be an object

这不是完全有用,因为现在我必须检查数百个项目才能找到有问题的项目。

但这是一个不同的问题,请考虑关闭!

您的架构没有任何问题。您在数组中遇到的错误是:

"value" must be an object, "value" at position 0 fails because 
[child "name" fails because ["name" length must be at least 3 characters long]]

没错,您的姓名密钥必须至少包含 3 个字符。

并且,如您所问,您可以从错误描述中获取失败的对象或 您还可以使用 any.error(err) 来跟踪这些对象。

例如,如果你想知道失败的数组索引,你可以这样做:

  const arraySchema = Joi.array().items(Joi.object(objectSchema)).required().error((errors) => {

    const indexes = errors.map((err) => err.path[0]);
    return new Error(`Indexes with error: ${indexes}`)
  })

对于这个对象数组:

[
  {
    'id': 11,
    'name': 'ABC'
  },
  {
    'id': 22,
    'name': 'ABC'
  },
  {
    'id': 33,
    'name': 'XY'
  },
  {
    'id': 44,
    'name': 'ABC'
  },
  {
    'id': 55,
    'name': 'XY'
  },
]

错误将是:

Indexes with error: 2,4

您可以通过以下方式访问您的错误消息:

validationResult.error.message

不要忘记在验证中使用 { abortEarly: false }

Joi.alternatives(objectSchema, arraySchema).validate(course, { abortEarly: false })

按照对数组的描述工作,但对非数组不显示任何内容,所以我做了一个小改动:

const arraySchema = 

Joi.array().items(Joi.object(objectSchema)).required().error((errors) => 
    {
        if (errors[0].path.length)
        {
            const indexes = errors.map((err) => err.path[0]);
            if (indexes.length) return new Error(`Indexes with error: ${indexes}`);
        }
        return errors;
    });

因此,如果它是一个数组,我 return 坏索引数组(如您所建议的)。但如果它是一个对象,我只是 return { errors } 不变。