【问题标题】:Hapi Joi - validate concatenated keysHapi Joi - 验证连接键
【发布时间】:2020-05-30 12:54:18
【问题描述】:

我有一个像这样的请求正文:

bod = {
file: '123654',
extension: 'bbb',
...
}

我正在使用 hapi joi 来验证它的字段:

let valSchema = {};
valSchema.play = Joi.object().keys({
    file: Joi.string().required().message("Invalid name. Please check documentation."),
    extension: Joi.string().empty().required().message("No extension sent. check the docs..."),
});

module.exports.valSchema = valSchema;

问题是其中一个验证需要检查“$file:$extension”是否在一个数组中,例如:

validConcatenations = [
    "1111:aaa","111123:bbb", "12312:aab",
    "21323:zzzs" ... ];

我需要这样做:

if (data.file && settings.fileWithExtensions.indexOf(`${data.file}:${data.extension}`) < 0) {
        return errors.invalidSampleRate;
    }

使用 joi...这可能使用它吗? 使用吗?

【问题讨论】:

  • 在数组哪里?因为这听起来像是一个完全独立的签入代码,与验证您的传入数据无关。它可能会立即遵循初始数据接受步骤,但不要将两者混为一谈:首先验证传入数据以确保 it 根据您的应用程序要求是正确的。验证失败有一个信号关于数据。如果结果不是它的数组条目,那不是验证失败,这是一个关于您的系统的信号,而不是数据本身。它不负责维护该数组。

标签: javascript joi hapi


【解决方案1】:

有可能,您只需要custom validation,如下例所示。

版本 16.1.8 或更高版本

'use strict';

const Joi = require('@hapi/joi');

const customValidation = function (value, helpers) {
    const validConcatenations = [
        "1111:aaa", "111123:bbb", "12312:aab", "21323:zzzs"];
    if (!validConcatenations.includes(`${value.file}:${value.extension}`)) {
        throw Error(`Wrong concatenation ${value.file}:${value.extension}`)
    }
    return value;
};

const schema = Joi.object().keys({
    file: Joi.string().required(),
    extension: Joi.string().empty().required(),
}).custom(customValidation);

const wrongData = { file: '123654', extension: 'bbb' };
const niceData = { file: '1111', extension: 'aaa' };

console.log(schema.validate(wrongData));
console.log(schema.validate(niceData));

输出:

{ value: { file: '123654', extension: 'bbb' },
  error: 
   { ValidationError: "value" failed custom validation because Wrong concatenation 123654:bbb
     _original: { file: '123654', extension: 'bbb' },
     details: [ [Object] ] } }
{ value: { file: '1111', extension: 'aaa' } }

查看the docs,从版本 12.1.0

开始可以执行以下解决方案

版本 12.1.0 或更高版本

'use strict';

const _Joi = require('@hapi/joi');

const custom = {
    base: _Joi.object(),
    name: 'custom',
    language: {
        concatenation: 'is a invalid concatenation',
    },
    rules: [
        {
            name: 'concatenation',
            validate(params, value, state, options) {
                const validConcatenations = [
                    "1111:aaa", "111123:bbb", "12312:aab", "21323:zzzs"];
                if (!validConcatenations.includes(`${value.file}:${value.extension}`)) {
                    return this.createError('custom.concatenation', {v: value}, state, options);
                }
                return value;
            }
        }
    ]
};

const Joi = _Joi.extend(custom);

const schema = Joi.custom().keys({
    file: Joi.string().required(),
    extension: Joi.string().empty().required(),
}).concatenation();

const wrongData = { file: '123654', extension: 'bbb' };
const niceData = { file: '1111', extension: 'aaa' };

console.log(schema.validate(wrongData));
console.log(schema.validate(niceData));

输出:

{ error: 
   { ValidationError: "value" is a invalid concatenation
    at Object.exports.process (/tmp/test/node_modules/@hapi/joi/lib/errors.js:202:19)
    at type._validateWithOptions (/tmp/test/node_modules/@hapi/joi/lib/types/any/index.js:762:31)
    at type.validate (/tmp/test/node_modules/@hapi/joi/lib/types/any/index.js:796:21)
    at Object.<anonymous> (/tmp/test/index.js:36:20)
    at Module._compile (module.js:653:30)
    at Object.Module._extensions..js (module.js:664:10)
    at Module.load (module.js:566:32)
    at tryModuleLoad (module.js:506:12)
    at Function.Module._load (module.js:498:3)
    at Function.Module.runMain (module.js:694:10)
     isJoi: true,
     name: 'ValidationError',
     details: [ [Object] ],
     _object: { file: '123654', extension: 'bbb' },
     annotate: [Function] },
  value: { file: '123654', extension: 'bbb' },
  then: [Function: then],
  catch: [Function: catch] }
{ error: null,
  value: { file: '1111', extension: 'aaa' },
  then: [Function: then],
  catch: [Function: catch] }

【讨论】:

  • "@hapi/joi": "^15.0.2" 返回 "TypeError: Joi.object(...).keys(...).custom 不是函数" :(
  • @Eunito 你不能将 Joi 升级到 16.1.8 或更高版本吗?
  • 不幸的是没有...会导致追溯问题!在 joi 对每个键都起作用之后,我需要对连接的键执行外验证...
猜你喜欢
  • 2018-09-24
  • 2013-10-19
  • 2019-10-10
  • 2018-05-25
  • 2018-07-25
  • 1970-01-01
  • 2018-06-25
  • 2015-04-29
  • 2015-07-01
相关资源
最近更新 更多