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

如何在Fastify中用Ajv验证逗号分隔查询字符串为数组?

解决Fastify中逗号分隔查询字符串数组的解析与验证问题

问题原因

Fastify默认使用qs库解析查询字符串,但默认配置不会自动将逗号分隔的字符串拆分为数组。因此userNo=1,2会被解析为单个字符串元素的数组['1,2'],而非预期的['1','2']。

解决方案

需要从查询字符串解析规则配置和Schema验证逻辑两方面调整,确保逗号分隔值被正确拆分并通过验证。

1. 开启Fastify的逗号分隔数组解析

在Fastify实例初始化时,配置querystring选项开启comma支持,让qs库自动拆分逗号分隔的数组值:

const fastify = Fastify({
  querystring: {
    comma: true // 核心配置:开启逗号分隔数组解析
  }
});

该配置是全局生效的,所有查询字符串中的逗号分隔数组都会被正确拆分。

2. 优化Schema定义(保持验证严谨性)

你的现有Schema已经正确定义了userNo为字符串数组,可根据参数是否可选调整Partial的使用,让验证逻辑更清晰:

import { Type } from '@fastify/type-provider-typebox';

// 如果userNo是必填参数
export const userNoSchema = Type.Object({
  userNo: Type.Array(Type.String())
}, { $id: 'userNo' });

// 如果userNo是可选参数
// export const userNoSchema = Type.Partial(
//   Type.Object({ userNo: Type.Array(Type.String()) }),
//   { $id: 'userNo' }
// );

3. 保持Ajv编译器配置不变

你当前的@fastify/ajv-compiler配置无需修改,只要查询字符串被正确解析为数组,Ajv会自动完成数组类型的验证。确保使用的是@fastify/ajv-compiler的稳定版本即可。

完整可运行示例

import Fastify from 'fastify';
import fp from 'fastify-plugin';
import { Type } from '@fastify/type-provider-typebox';
import fstAjvCompiler from '@fastify/ajv-compiler';

// Schema定义
export const userNoSchema = Type.Partial(
  Type.Object({
    userNo: Type.Array(Type.String())
  }),
  { $id: 'userNo' }
);

const getSchema = {
  querystring: Type.Ref(userNoSchema),
  response: {
    200: Type.Object({
      data: Type.Record(Type.String(), Type.String())
    })
  }
};

// Fastify插件
export default fp((instance, options, done) => {
  instance.addSchema(userNoSchema);

  const factory = fstAjvCompiler();
  const schemas = instance.getSchemas() as Parameters<typeof factory>[0];

  const validator = factory(schemas, {
    customOptions: { keywords: ['instanceOf', 'example'] }
  });
  instance.setValidatorCompiler(validator);

  // 注册测试路由
  instance.get('/api/v1/users/', { schema: getSchema }, (request, reply) => {
    console.log(request.query.userNo); // 输出 ['1','2']
    reply.send({ data: { status: 'success' } });
  });

  done();
});

// 初始化Fastify实例
const fastify = Fastify({
  querystring: {
    comma: true
  }
});

fastify.register(import('./your-plugin-file.js'));

fastify.listen({ port: 3000 }, (err) => {
  if (err) throw err;
  console.log('Server running on http://127.0.0.1:3000');
});

验证测试

发送请求http://127.0.0.1:3000/api/v1/users/?userNo=1,2,此时request.query.userNo会被正确解析为['1','2'],且能通过Ajv的数组类型验证。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 23:20:22