【问题标题】:Validating with dynamic context objects in Joi在 Joi 中使用动态上下文对象进行验证
【发布时间】:2019-11-01 09:51:24
【问题描述】:

我需要使用动态对象来验证值。该对象定期更改,因此我在运行时将其下载并在本地保存为格式良好的 .json 文件。我需要将这些值输入到对Joi.validate 的调用中(通过'context' 选项)并验证数组中的项目是否与上下文对象中的键/值对之一匹配。

// the defined schema
const schema = Joi.object().keys({
  'foo': Joi.array()
    .unique()
    .items(
      // these items need to match the keys/values from the context object
      Joi.object().keys({
        id: Joi.string()
          .required(), // this needs to be a key from the context object
        name: Joi.string()
          .required(), // this needs to be the value from the context object for the key defined by the above id property
      }),
    )
})

// the .json file with the context object looks as such
{
  "id of first thing": "name of first thing",
  "id of second thing": "name of second thing",
  ...
}

// validation is done like this:
Joi.validate(theThingsToValidate, schema, {context: objectFromTheJsonFile});

【问题讨论】:

  • 您从未指定您是否遇到错误或它不起作用或您应该如何编写代码?

标签: javascript json validation schema joi


【解决方案1】:

您可以在每次检测到文件已更改时动态构建架构。在这种情况下,我认为您不需要 context 选项,除非我误解了您的问题。

在我的示例代码中,foo 数组中要验证的每个元素都采用以下格式

{
    id : 'id of thing',
    name: 'name of thing'
}

并且必须以这种格式匹配文件中的元素之一

{
  "id of first thing": "name of first thing",
  "id of second thing": "name of second thing",
  ...
}

转换文件中的数据以构建所有有效对象的列表并将其传递给Joi.array().items 应该可以正确实现预期的目标。

const fs = require('fs');
const path = require('path');

let schema;
let lastUpdate = 0;

// Assumes your file exists and is correctly json-formatted
// You should add some error handling
// This might also need to be tweaked if you want it to work in an asynchronous way
function check(theThingsToValidate) {
    let jsonPath = path.resolve(__dirname, 'data.json');
    let fileStats = fs.statSync(jsonPath);
    if (!schema || fileStats.mtimeMs > lastUpdate) {
        lastUpdate = fileStats.mtimeMs;
        let fileData = JSON.parse(fs.readFileSync(jsonPath, 'utf8'));
        schema = Joi.object().keys({
            'foo': Joi.array().unique().items(
                ...Object.keys(fileData).map(key => ({
                    id: key,
                    name: fileData[key]
                }))
            )
        });
    }

    return Joi.validate(theThingsToValidate, schema);
}

注意:mtimeMs 已在 Node 8 中添加,因此如果您运行的是较低版本,可能需要更改它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-19
    • 2020-02-21
    • 2020-05-11
    • 2020-08-04
    • 2018-02-27
    • 2020-03-01
    • 1970-01-01
    • 2019-07-31
    相关资源
    最近更新 更多