带有完美消息的 JSON 模式验证
Posted
技术标签:
【中文标题】带有完美消息的 JSON 模式验证【英文标题】:JSON schema validation with perfect messages 【发布时间】:2018-05-07 04:06:42 【问题描述】:我将 REST 调用中的数据条目分为 4 个部分。数据可以通过以下方式发送到 REST 调用:-
-
标题
查询参数
路径参数
请求正文
因此,为了验证上述 4 个部分中是否存在任何键,我以这种格式创建了一个模式。因此,如果我必须验证查询参数中的任何内容,我将添加键“查询”,然后在其中添加字段,这需要验证
const schema =
id: 'Users_login_post',
type: 'object',
additionalProperties: false,
properties:
headers:
type: 'object',
additionalProperties: false,
properties:
Authorization:
type: 'string',
minLength: 10,
description: 'Bearer token of the user.',
errorMessages:
type: 'should be a string',
minLength: 'should be atleast of 23 length',
required: 'should have Authorization'
,
required: ['Authorization']
,
path:
type: 'object',
additionalProperties: false,
properties:
orgId:
type: 'string',
minLength: 23,
maxLength: 36,
description: 'OrgId Id of the Organization.',
errorMessages:
type: 'should be a string',
minLength: 'should be atleast of 23 length', // ---> B
maxLength: 'should not be more than 36 length',
required: 'should have OrgId'
,
required: ['orgId']
;
现在,在我的 express 代码中,我创建了一个请求对象,以便我可以测试这种格式的 JSON 的有效性。
router.get("/org/:orgId/abc", function(req, res)
var request = //---> A
path:
orgId : req.params.orgId
,
headers:
Authorization : req.headers.Authorization
const Ajv = require('ajv');
const ajv = new Ajv(
allErrors: true,
);
let result = ajv.validate(schema, request);
console.log(ajv.errorsText());
);
我使用 AjV 针对我的架构验证上述请求对象(在 A 处)。
我得到的输出如下所示:
data/headers should have required property 'Authorization', data/params/orgId should NOT be shorter than 23 characters
现在我有一个问题清单:
-
为什么消息在 data/headers 和 data/params/orgId 中显示 data 字样,即使我的变量名是 请求(在 A 处)
还有为什么不使用我的 errormessages,就像我提到的 orgId 的情况:应该至少 23 长度(在 B 处)作为一条消息,即使在那时消息也不应短于 23 个字符。
如何显示 request/headers 而不是 data/headers。
另外,我用来验证路径参数、查询参数、标题参数、正文参数的方式,这是正确的方式吗?如果不是,那么还有什么更好的方式来做同样的事情?
请多指教。
提前致谢。
【问题讨论】:
【参考方案1】:使用 ajv 关键字
import Ajv from 'ajv';
import AjvKeywords from 'ajv-keywords';
// ajv-errors needed for errorMessage
import AjvErrors from 'ajv-errors';
const ajv = new Ajv.default( allErrors: true );
AjvKeywords(ajv, "regexp");
AjvErrors(ajv);
// modification of regex by requiring Z https://www.regextester.com/97766
const ISO8601UTCRegex = /^(-?(?:[1-9][0-9]*)?[0-9]4)-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]+)?Z$/;
const typeISO8601UTC =
"type": "string",
"regexp": ISO8601UTCRegex.toString(),
"errorMessage": "must be string of format 1970-01-01T00:00:00Z. Got $0",
;
const schema =
type: "object",
properties:
foo: type: "number", minimum: 0 ,
timestamp: typeISO8601UTC,
,
required: ["foo", "timestamp"],
additionalProperties: false,
;
const validate = ajv.compile(schema);
const data = foo: 1, timestamp: "2020-01-11T20:28:00"
if (validate(data))
console.log(JSON.stringify(data, null, 2));
else
console.log(JSON.stringify(validate.errors, null, 2));
https://github.com/rofrol/ajv-regexp-errormessage-example
【讨论】:
【参考方案2】:AJV 无法知道您传递给验证函数的变量的名称。
但是,您应该能够从 errors
数组中找出哪些路径失败(以及为什么)并从那里构造您的消息。
见https://ajv.js.org/#validation-errors
要在架构中使用自定义错误消息,您需要一个 AJV 插件:ajv-errors。
见https://github.com/epoberezkin/ajv-errors
【讨论】:
以上是关于带有完美消息的 JSON 模式验证的主要内容,如果未能解决你的问题,请参考以下文章
如何使用具有必填字段的 JSON 模式验证 http PATCH 数据