如何为多个Fastify路由共享参数Schema?
Fastify 批量共享路由参数 Schema 的方案
1. 插件封装法(最推荐)
把这组带共同前缀的路由封装成独立插件,在插件内部注册全局可复用的参数Schema片段,所有路由直接引用即可:
// 定义共享的id参数Schema const idParamSchema = { type: 'string', format: 'uuid', // 按你的实际需求调整格式规则 description: '配置项唯一ID' }; // 创建路由插件 async function jobsRoutes(fastify, options) { // 注册全局Schema片段,给个唯一标识$id fastify.addSchema({ $id: 'configurationIdParam', type: 'object', properties: { id: idParamSchema }, required: ['id'] }); // 所有路由直接引用这个全局Schema fastify.get('/', { schema: { params: { $ref: 'configurationIdParam#' } } }, async (req, reply) => { return { configurationId: req.params.id }; }); fastify.post('/:jobId', { schema: { params: { $ref: 'configurationIdParam#', // 追加当前路由独有的参数Schema jobId: { type: 'string', minLength: 3 } } } }, async (req, reply) => { return { configurationId: req.params.id, jobId: req.params.jobId }; }); } // 注册插件并指定前缀 fastify.register(jobsRoutes, { prefix: '/configuration/:id/jobs' });
2. 路由工厂函数法
写一个简单的工厂函数,自动帮你把共享参数Schema合并到每个路由的配置里,不用手动重复写:
// 定义共享的id参数Schema const sharedParams = { id: { type: 'string', format: 'uuid' }, required: ['id'] }; // 路由工厂:自动合并共享参数 function withSharedParams(routeOpts, handler) { return { ...routeOpts, schema: { ...routeOpts.schema, params: { ...sharedParams, ...(routeOpts.schema?.params || {}) } }, handler }; } // 使用示例 fastify.get('/configuration/:id/jobs', withSharedParams({}, async (req, reply) => { // 处理逻辑 })); fastify.post('/configuration/:id/jobs/:jobId', withSharedParams({ schema: { params: { jobId: { type: 'string' } } } }, async (req, reply) => { // 处理逻辑 }));
3. onRoute钩子全局注入法
通过Fastify的onRoute钩子,在路由注册时自动给匹配前缀的路由加上共享参数Schema:
fastify.register(async (instance) => { // 监听路由注册事件 instance.addHook('onRoute', (routeOpts) => { // 只给目标前缀的路由注入Schema if (routeOpts.url.startsWith('/configuration/:id/jobs')) { routeOpts.schema = routeOpts.schema || {}; routeOpts.schema.params = { id: { type: 'string', format: 'uuid' }, required: ['id'], ...(routeOpts.schema.params || {}) }; } }); // 直接注册路由,不用手动加params Schema instance.get('/configuration/:id/jobs', async (req, reply) => { // 处理逻辑 }); instance.post('/configuration/:id/jobs/:jobId', async (req, reply) => { // 处理逻辑 }); });
这三种方案都能避免重复编写:id的Schema,其中插件封装的方式最贴合Fastify的设计思路,也更便于后续维护和复用。
内容的提问来源于stack exchange,提问作者Raz Luvaton
相关产品推荐
相关产品推荐

