Skip to content

Validation参数校验

Vona 基于Zod 提供了非常简洁、灵活的机制对请求参数作校验

1. 自动推断Zod Schema:基础类型/Dto/Entity

如果参数类型是基础类型/Dto/Entity,那么,系统就会自动推断出对应的 Zod Schema,从而进行校验

比如,findOne(@Arg.query('id') id: number),id 的类型是number,那么自动推断出来的 Schema 就是:z.number()

再比如,findOne(@Arg.query() query: DtoStudentInfo),query 的类型是 Dto: DtoStudentInfo,那么自动推断出来的 Schema 就是:z.object({...})

  • 可自动推断的类型清单
名称说明
stringz.string()
numberz.number()
booleanz.boolean()
Dtoz.object({...})
Entityz.object({...})

2. 指定Zod Schema

我们还可以显式的指定 Zod Schema,从而提供更加复杂的校验规则。比如,URL 为/?id=1,我们要求 id 为number,并且>=6。那么,我们可以给 query 传入参数:z.number().min(6)

typescript
import z from 'zod';

class ControllerStudent3 {
  @Web.get()
  findOne(@Arg.query('id', z.number().min(6)) id: number) {}
}

3. 扩展Zod Schema的属性

我们还可以在现有的 Zod Schema 基础之上扩展新的属性

比如,我们要指定 id 为number,并且是可选,默认值为3

typescript
import { v } from 'vona-module-a-openapi';

class ControllerStudent3 {
  @Web.get()
  findOne(@Arg.query('id', v.default(3), v.optional()) id: number) {}
}

首先,系统自动推断出 schema 为z.number(),然后,依次附加optionaldefault属性,最终会生成 schema:z.number().optional().default(3)

因此,上述代码等价于:

typescript
class ControllerStudent3 {
  @Web.get()
  findOne(@Arg.query('id', z.number().optional().default(3)) id: number) {}
}

也等价于:

typescript
class ControllerStudent3 {
  @Web.get()
  findOne(@Arg.query('id', v.default(3), z.number().optional()) id: number) {}
}

4. 装饰器:@Arg.filter

装饰器@Arg.filter支持更高级的 Query 参数,包括:columns/where/orders/pageNo/pageSize

5. 工具:v.array

对于 Array 类型的参数,Vona 也提供了便利的工具。比如,我们要求 ids 为number[]

typescript
class ControllerStudent3 {
  @Web.get()
  findOne(@Arg.query('ids', v.array(Number)) ids: number[]) {}
}

等价于:

typescript
class ControllerStudent3 {
  @Web.get()
  findOne(@Arg.query('ids', v.array(z.number())) ids: number[]) {}
}

再比如,我们从 Request body 获取 students 数组,类型为DtoStudentInfo[]

typescript
class ControllerStudent3 {
  @Web.post()
  update(@Arg.body('students', v.array(DtoStudentInfo)) students: DtoStudentInfo[]) {}
}

6. 工具:v.lazy

对于可能导致循环引用的 Class,可以使用v.lazy创建 lazy schema:

typescript
@Dto()
export class DtoUserLazy {
  @Api.field(v.optional(), v.lazy(() => DtoUserLazy))
  user?: DtoUserLazy;

  @Api.field(v.optional(), v.array(v.lazy(() => DtoRoleLazy)))
  roles?: DtoRoleLazy[];
}

装饰器清单

名称说明
@Arg.param从Request Params中取值
@Arg.query从Request Query中取值
@Arg.body从Request Body中取值
@Arg.headers从Request Headers中取值
@Arg.fields从Request Upload中取值
@Arg.field从Request Upload中取值
@Arg.files从Request Upload中取值
@Arg.file从Request Upload中取值
@Arg.user取得当前用户
@Arg.filter从Request Query中取值

工具清单

VonaJS 将用于扩展 Zod Schema 的工具方法都放入分组v中,从而减轻心智负担

1. Basic Tools

名称说明
v.required不允许为空提供自定义错误消息,否则使用Zod内置的错误消息
v.optionaloptional
v.defaultdefault
v.objectobject
v.strictObjectSame as z.strictObject(schema.shape)
v.looseObjectSame as z.looseObject(schema.shape)
v.arrayarray
v.lazy创建Lazy Schema

2. String Tools

名称说明
v.emailemail
v.urlurl
v.uuiduuid
v.ipv4ipv4
v.ipv6ipv6
v.min支持string/number
v.max支持string/number
v.trimtrim
v.toLowerCasetoLowerCase
v.toUpperCasetoUpperCase
v.lowercaselowercase
v.uppercaseuppercase
v.regexregex

3. Openapi Tools

名称说明
v.openapiopenapi
v.titletitle
v.descriptiondescription
v.exampleexample

4. Serializer Tools

名称说明
serializerExclude排除字段
serializerTransform转换字段值
serializerSensitive字段脱敏处理
serializerGetter使用Getter生成字段值

5. Zod Tools

名称说明
v.refine提供Zod Refine能力
v.transform提供Zod Transform能力

6. Special Tools

名称说明
v.tableIdentity基于当前系统配置,提供number或者bigint的校验规则
v.captcha提供验证码选项

基于 MIT 许可发布