首页 > 解决方案 > Node Joi:joi键的值必须与joi数组中的一个对象键匹配

问题描述

这是我的 Joi 架构

const createRoom = {
  body: {
    createdBy: Joi.string().required(),
    members: Joi.array().min(2).max(2).items(
      Joi.object().keys({
        id: Joi.string().required(),
        name: Joi.string().required(),
      })
    ).unique('id').required()
  }
}

我想要的是

的值createdBy必须与成员数组中的一个唯一对象 id 匹配

例子

这个输入应该通过

{
  createdBy: 'abcd1234',
  members: [
    {
      id: 'abcd1234',
      name: "john"
    },
    {
      id: 'xyz1234',
      name: "john"
    }
  ]
}

此输入应失败

{
  createdBy: 'abcd1234',
  members: [
    {
      id: 'bcdf1234',
      name: "john"
    },
    {
      id: 'xyz1234',
      name: "john"
    }
  ]
}

joi可以做到吗?我在Joi Docs中没有找到类似的东西。

标签: node.jsvalidationschemajoi

解决方案


您可以将array.hasref结合使用:

const schema = Joi.object({
 createdBy: Joi.string().required(),
 members: Joi.array().min(2).max(2).items(
    Joi.object().keys({
        id: Joi.string().required(),
        name: Joi.string().required(),
    }))
    .has(Joi.object({ 
        id: Joi.string().required().valid(Joi.ref('$createdBy')),
        name: Joi.string()
    }))
    .unique('id')
})

使用 array.has 您是说您希望数组中至少有一个对象。Joi.ref 允许您访问当前对象的任何值。

这意味着以下对象将通过:

const validObj = {
  createdBy: 'abcd1234',
  members: [
    {
      id: 'abcd1234',
      name: "john"
    },
    {
      id: 'xyz1234',
      name: "john"
    }
  ]
}

schema.validate(validObj, { context: validObj })

这将失败:

const invalidObj = {
  createdBy: 'abcd1234',
  members: [
    {
      id: 'xxxx',
      name: "john"
    },
    {
      id: 'xyz1234',
      name: "john"
    }
  ]
}

schema.validate(invalidObj, { context: invalidObj })

这也将失败,因为有重复:

const invalidObj = {
  createdBy: 'abcd1234',
  members: [
    {
      id: 'abcd1234',
      name: "john"
    },
    {
      id: 'abcd1234',
      name: "john"
    }
  ]
}

schema.validate(invalidObj, { context: invalidObj })

推荐阅读