You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Fastify使用Ajv时避免重复创建函数的最佳实践及代码疑问

Fastify验证/序列化避免重复创建函数的最佳实践

问题背景

⚠ 安全提示
请将 Schema 定义视为应用代码。验证和序列化功能会通过 new Function() 动态执行代码,使用用户提供的 Schema 存在安全风险。
另外,尽管 Fastify 支持 Ajv 的 $async 特性,但不应将其作为首要验证策略。该选项用于在验证过程中访问数据库,这可能导致应用遭受拒绝服务攻击。如果需要执行异步任务,请在验证完成后使用 Fastify 的钩子(如 preHandler)。

用户当前代码示例:

const PostMovieBody = {
  type: 'object',
  properties: {
    title: { type: 'string' },
    releaseYear: { type: 'integer', minimum: 1878 },
  },
}

app.post('/movie', {
  schema: {
    // 引用 Schema
    body: PostMovieBody,
    '2xx': {
      type: 'object',
      properties: {
        value: { type: 'string' },
        otherValue: { type: 'boolean' }
      }
    },
  },
})

用户疑问:该示例是否会每次创建新函数?若是,该如何避免?使用验证/序列化时,避免每次创建新函数的最佳实践是什么?


解答

你的代码是否会重复创建函数?

不会。Fastify 内部会对传入的 Schema 进行缓存,在应用启动阶段就会基于 Schema 生成对应的验证/序列化函数,之后每次请求都会复用这些预生成的函数,不会在每次请求时重新创建。

避免重复创建函数的最佳实践

  • 复用 Schema 对象:像你代码中这样把 Schema 定义为全局常量(如 PostMovieBody),而不是在路由配置内部动态生成 Schema 对象。这样 Fastify 能准确识别同一个 Schema,避免重复编译。
  • 依赖默认缓存机制:Fastify 默认使用的 Ajv 验证器本身自带缓存功能,只要你不每次传入全新的匿名 Schema 对象,就能自动命中缓存,避免重复生成函数。
  • 禁止动态修改 Schema:如果在运行时动态修改已定义的 Schema 内容,会触发 Fastify/Ajv 重新编译函数。尽量在应用启动前就确定好所有 Schema 的结构。
  • 使用 Schema 引用($ref):对于重复使用的 Schema 片段,用 $ref 引用集中管理的 Schema,既减少代码冗余,又能确保同一片段只被编译一次。示例:
    // 集中定义可复用 Schema
    const schemas = {
      PostMovieBody: {
        $id: 'postMovieBody',
        type: 'object',
        properties: {
          title: { type: 'string' },
          releaseYear: { type: 'integer', minimum: 1878 },
        }
      }
    }
    
    // 注册所有 Schema 到 Fastify
    app.addSchema(schemas.PostMovieBody)
    
    // 在路由中引用
    app.post('/movie', {
      schema: {
        body: { $ref: 'postMovieBody' },
        // ... 其他 Schema 配置
      }
    })
    
  • 杜绝动态生成 Schema:不要在请求处理过程或路由注册时,根据用户输入等动态拼接 Schema。这不仅会触发重复编译,还违反安全提示中「不可使用用户提供的 Schema」的要求。

内容的提问来源于stack exchange,提问作者lambdamaster

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 23:16:10