自引用JSON Schema在Fastify中触发Maximum call stack size exceeded报错
问题根因
你遇到的栈溢出问题不是JSON Schema本身不合法,而是Fastify默认依赖的序列化库fast-json-stringify的工作机制导致的:
- 常规JSON Schema校验工具是惰性解析引用的,只会在实际校验对应字段的时候才会解析引用,不会全量展开Schema结构
fast-json-stringify为了生成高性能的序列化函数,会在服务启动阶段全量展开所有$ref生成最终的序列化逻辑,你第二个Schema里foo -> properties.bar -> properties.bang -> items -> $ref: #/definitions/foo形成了无终止的递归引用,展开时就会触发调用栈溢出。
第一个Schema能正常运行是因为bang的类型是对象,additionalProperties的引用解析不会被直接全量递归展开,所以没有触发栈溢出。
解决方案
方案1:配置fast-json-stringify开启循环引用支持+限制递归深度
Fastify初始化时传入序列化配置,开启循环引用支持,同时设置最大递归深度适配你的业务场景:
const fastify = require('fastify')({ serializerOpts: { circular: true, // 开启循环引用支持 maxDepth: 10 // 按你实际业务中数据的最大层级设置即可 } })
如果你的Fastify版本较低,还可以同步调整AJV校验的配置避免校验阶段也出现同类问题:
const fastify = require('fastify')({ ajv: { customOptions: { strict: false, loopRequired: Infinity } }, serializerOpts: { circular: true, maxDepth: 10 } })
方案2:调整Schema结构避免无限展开
如果不想修改全局配置,你可以修改Schema结构,给自引用路径加一个层级终止的逻辑,比如用anyOf加边界限制,不会影响你实际的校验逻辑,只是给fast-json-stringify的展开逻辑一个终止边界:
"bang": { "type": "array", "items": { "$ref": "#/definitions/foo" }, "maxItems": 100 }
内容的提问来源于stack exchange,提问作者Ugo Lfe
相关产品推荐
相关产品推荐

