求FASTIFY全局HOOK实现:自动序列化所有app.ts端点指定类型值
在Fastify中实现全局自动序列化特定值的方案
如果你想不用手动调用.toString(),让所有端点的响应自动序列化特定类型的值,可以用以下两种全局方案:
方案1:全局onSend钩子(响应发送前处理)
这个钩子会拦截所有即将发送的响应,你可以在这里遍历响应数据并转换目标值:
// 在app.ts中注册全局钩子 app.addHook('onSend', async (request, reply, payload) => { // 非JSON格式的响应直接返回 if (typeof payload !== 'string') return payload; let responseData; try { responseData = JSON.parse(payload); } catch (err) { return payload; } // 递归遍历转换目标类型 const transform = (val) => { // 替换成你需要检测的类型判断逻辑,比如判断是否是ObjectId if (val && typeof val === 'object' && val.toString && val.constructor.name === 'ObjectId') { return val.toString(); } if (Array.isArray(val)) { return val.map(transform); } if (val && typeof val === 'object') { const result = {}; for (const key in val) { result[key] = transform(val[key]); } return result; } return val; }; return JSON.stringify(transform(responseData)); });
方案2:全局自定义JSON序列化器
直接替换Fastify默认的JSON序列化逻辑,所有响应都会用这个规则处理,性能更优:
// 创建Fastify实例时配置全局序列化器 const fastify = require('fastify')({ serializer: (payload) => { const replacer = (key, val) => { // 这里写你的类型判断,比如匹配需要转字符串的类型 if (val && typeof val === 'object' && val.toString && val.constructor.name === 'ObjectId') { return val.toString(); } return val; }; return JSON.stringify(payload, replacer); } });
关键注意点
- 精准类型判断:把示例中的
ObjectId判断替换成你实际遇到的类型(比如自定义类、特定内置类型),可以通过instanceof、constructor.name或者对象的特征属性来判断。 - 避免误转换:如果有不需要处理的对象(比如
Date),要在判断逻辑里排除,防止意外修改数据格式。 - 性能对比:方案2的序列化器直接在序列化阶段处理,不需要先解析再重新序列化,比方案1更高效,推荐优先使用。
内容的提问来源于stack exchange,提问作者Brayan Vinicius Jordan
相关产品推荐
相关产品推荐

