4

我将 REST 调用中的数据条目分为 4 个部分。数据可以通过以下方式发送到 REST 调用:-

  1. 标题
  2. 查询参数
  3. 路径参数
  4. 请求正文

因此,为了验证上述 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']
   }
 }
};

现在,在我的快速代码中,我创建了一个请求对象,以便我可以测试这种格式的 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

现在我有一个问题清单:

  1. 为什么即使我的变量名称是request(在 A 处) ,消息也会在data/headersdata/params/orgId中显示数据
  2. 另外为什么不使用我的错误消息,就像我提到的 orgId 的情况一样:应该至少23长度(在 B 处)作为消息,即使这样消息来也不应该短于 23 个字符
  3. 如何显示request/headers而不是data/headers

另外,我用来验证路径参数、查询参数、标题参数、正文参数的方式是正确的方式,如果不是,那么还有什么更好的方式来做同样的事情?

请阐明一些观点。

提前致谢。

4

2 回答 2

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

于 2021-01-11T19:58:54.573 回答
0

AJV 无法知道您传递给验证函数的变量的名称。

但是,您应该能够从errors数组中找出哪些路径失败(以及为什么)并从那里构造您的消息。

https://ajv.js.org/#validation-errors

要在架构中使用自定义错误消息,您需要一个 AJV 插件:ajv-errors。

https://github.com/epoberezkin/ajv-errors

于 2018-11-13T00:19:40.263 回答