用于验证多个动态关键对象的Joi模式

时间:2019-03-09 11:29:13

标签: javascript hapijs joi

Joi v14.3.1

有一个物体:

const obj = {
  actions: {
    dynamic_key_0: {
      email: {
        to: 'batman@mail.com'
      }
    },
    dynamic_key_1: {
      webhook: {
        host: 'batman.com',
        method: 'get'
      }
    }
  }
};

其中dynamic_key_0dynamic_key_1键名可以是任何名称。另外,可以有很多这样的键。

我尝试了.pattern()

const Joi = require('joi');

const obj = {
  actions: {
    dynamic_key_0: {
      email: {
        to: 'batman@mail.com'
      }
    },
    dynamic_key_1: {
      webhook: {
        host: 'batman.com',
        method: 'get'
      }
    }
  }
};

const emailSchema = Joi.object().pattern(Joi.string(), Joi.object({
  email: Joi.object({
    to: Joi.string().email()
  })
}));

const webhookSchema = Joi.object().pattern(Joi.string(), Joi.object({
  webhook: Joi.object({
    host: Joi.string(),
    method: Joi.string()
  })
}));

const objSchema = Joi.object({
  actions: Joi.object()
    .concat(emailSchema)
    .concat(webhookSchema)
});

console.log(Joi.validate(obj, objSchema));

并收到以下验证错误。密钥email不允许。

{ error:
   { ValidationError: child "actions" fails because [child "dynamic_key_0" fails because ["email" is not allowed]]
       at Object.exports.process (/path/node_modules/joi/lib/errors.js:203:19)
       at internals.Object._validateWithOptions (/path/node_modules/joi/lib/types/any/index.js:764:31)
       at module.exports.internals.Any.root.validate (/path/node_modules/joi/lib/index.js:147:23)
       at Object.<anonymous> (/path/server/schema/test.js:38:17)
       at Module._compile (internal/modules/cjs/loader.js:689:30)
       at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
       at Module.load (internal/modules/cjs/loader.js:599:32)
       at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
       at Function.Module._load (internal/modules/cjs/loader.js:530:3)
       at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)
     isJoi: true,
     name: 'ValidationError',
     details: [ [Object] ],
     _object: { actions: [Object] },
     annotate: [Function] },
  value:
   { actions: { dynamic_key_0: [Object], dynamic_key_1: [Object] } },
  then: [Function: then],
  catch: [Function: catch] }

如何定义正确的架构来验证obj

1 个答案:

答案 0 :(得分:0)

我想出了下面的代码,看起来不错

const Joi = require('joi');

const obj = {
  actions: {
    dynamic_key_0: {
      email: {
        to: 'batman@mail.com'
      }
    },
    dynamic_key_1: {
      webhook: {
        host: 'batman.com',
        method: 'get'
      }
    }
  }
};

const emailSchema = Joi.object({
  email: Joi.object({
    to: Joi.string().email().required()
  })
});

const webhookSchema = Joi.object({
  webhook: Joi.object({
    host: Joi.string().required(),
    method: Joi.string()
  })
});

const objSchema = Joi.object({
  actions: Joi.object().pattern(
    Joi.string(),
    Joi.object()
      .concat(emailSchema)
      .concat(webhookSchema)
  )
});

console.log(Joi.validate(obj, objSchema));

结果:

{ error: null,
  value:
   { actions: { dynamic_key_0: [Object], dynamic_key_1: [Object] } },
  then: [Function: then],
  catch: [Function: catch] }