提问者:小点点

我应该总是在Express中编译Ajv模式吗?


我想使用Ajv验证器来验证我的express应用程序的请求主体。

要使用验证器,我们首先需要编译我们要测试的模式,然后运行验证,如下所示:

const Ajv = require('Ajv');
const ajv = new Ajv();

const schema = {
  type: 'object',
  required: ['username', 'password'],
  properties: {
    username: {
      type: 'string',
      minLength: 3,
    },
    password: {
      type: 'string',
      minLength: 8,
    },
  },
};

/* What we want to validate */
const body = {
  username: 'johndoe',
  password: 'secret'
};

/* We compile the validator */
const validate = ajv.compile(schema.query)

/* We test our data to see if it is valid */
const valid = validate(body)

我应该在endpoint被调用时始终编译验证器,并将其包含在路由中,还是可以将编译过程留在路由主体之外?


共2个答案

匿名用户

您应该在路由处理程序之外编译它一次,然后在处理程序中重用编译后的模式。

这将提高性能--您只需要在它发生变化时对其进行编译。

匿名用户

在试用了Josh Wulf的答案之后,我确认它在路由的处理程序之外编译验证器是可行的。

虽然它按预期工作,并且可以在路由处理程序之外编译,但我注意到它有一个缺点。

了解验证程序检测到哪些错误的方法是调用validate.errors:

var validate = ajv.compile(schema);
var valid = validate(data);

if (!valid) {
  console.log(validate.errors);
}

因此,我们不应该在路由的处理程序之外编译验证器,因为可能会出现并发问题。

由于针对同一路由的不同请求,验证器是相同的,因此访问验证器的errors属性可能会返回另一个客户机的错误。