缓存验证规则

未匹配的标注

使用schema.create方法创建的模式首先编译为可执行函数,然后执行以根据定义的规则验证数据。

在验证开始之前,编译过程确实需要几毫秒。但是,根据你的性能预期,你可能需要考虑缓存已编译的模式,因此不要为每个请求支付编译费用。

使用cacheKey

你可以通过定义唯一的cacheKey来缓存模式。你可以使用任何方法生成此缓存密钥,也可以在 HTTP 请求期间依赖ctx.routeKey

await request.validate({
  schema: schema.create({...}),
  cacheKey: ctx.routeKey,
})
  • request.validate的第一次调用将编译模式并将输出保存为对cacheKey的引用。
  • cacheKey相同之前,验证器不会重新编译模式。

缓存注意事项

任何形式的缓存都不是免费的,模式缓存也是如此。如果你的架构依赖于运行时值,那么缓存架构将不会提供所需的结果。考虑以下示例:

  • 你正在创建一个接受用户 state 和他们的 city 的表单。
  • cacheKey相同之前,验证器不会重新编译模式。
/**
 * 缓存注意事项
 */
const STATES = []
const CITIES = {}

export default class AddressValidator {
  public selectedState = this.ctx.request.input('state') // 👈

  public schema = schema.create({
    state: schema.enum(STATES),
    city: schema.enum(CITIES[this.selectedState] || [])
  })
}

如果你查看上面的示例,city的枚举选项取决于selectedState并且可能随每个 HTTP 请求而变化。

但是,由于我们启用了模式缓存。在第一个请求之后的 enum 选项将被缓存,并且即使用户选择了不同的状态也不会改变。

现在你已经了解了缓存的工作原理。让我们探索在验证模式中使用动态数据的一些不同方法。

放弃缓存

第一种选择是放弃缓存。这将给请求增加几毫秒的延迟,但却为你在模式定义中使用运行时值提供了最直接的 API。

创建唯一密钥

考虑到上面的例子,你可以将选择的状态附加到 cacheKey 中,因此每个状态都会有一个缓存模式的副本。例如:

export default class AddressValidator {
  public selectedState = this.ctx.request.input('state')

  public schema = schema.create({
    state: schema.enum(STATES),
    city: schema.enum(CITIES[this.selectedState] || [])
  })

  public cacheKey = `${this.ctx.routeKey}-${selectedState}`
}

上述方法也有其自身的缺点。例如,如果有 37 种状态,那么同一模式的缓存副本将有 37 个,只是略有不同。此外,如果需要多个动态值,这个数字将呈指数增长。

放弃缓存要比缓存太多略有变化的模式要好。

使用 Ref

Refs 给你两全其美。你仍然可以缓存模式并引用其中的运行时值。下面是一个例子:

export default class AddressValidator {
  public selectedState = this.ctx.request.input('state')

  public refs = schema.refs({
    cities: CITIES[this.selectedState] || []
  })

  public schema = schema.create({
    state: schema.enum(STATES),
    city: schema.enum(this.refs.cities)
  })
}

不是直接引用 CITIES[this.selectedState],而是将其移动到 schema.refs 对象,然后从那里开始,CITIES 将在运行时被拾取,而无需重新编译模式。

注:Ref只有在 验证规则模式类型 支持它们时才起作用。

本文章首发在 LearnKu.com 网站上。

本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://learnku.com/docs/adonisjs/5.x/va...

译文地址:https://learnku.com/docs/adonisjs/5.x/va...

上一篇 下一篇
贡献者:2
讨论数量: 0
发起讨论 只看当前版本


暂无话题~