Zod
Zod 是 TypeScript 优先的 Schema 声明和验证库。这里的 “Schema” 一词泛指任何数据类型,从简单的字符串到复杂的嵌套对象。
Zod 的设计尽可能方便开发人员使用。我们的目标是消除重复的类型声明。有了 Zod,你只需声明一次验证器,Zod 就会自动推断出 TypeScript 的静态类型。将较简单的类型组成复杂的数据结构也很容易。
@gqloom/zod
提供了 GQLoom 与 Zod 的集成,以便将 Zod Schema 编织成 GraphQL Schema。
安装
定义简单标量
在 GQLoom 中,可以直接使用 Zod Schema 作为丝线使用:
编织 | Weave
为了让 GQLoom
能正确地将 Zod Schema 编织到 GraphQL Schema,我们在使用 weave
函数时,需要添加来自 @gqloom/zod
的 ZodWeaver
。
定义对象
我们可以使用 Zod 定义对象,并将其作为丝线使用:
名称和更多元数据
为对象定义名称
在 GQLoom
中,我们有多种方法来为对象定义名称。
使用 __typename
字面量
在上面的代码中,我们使用 __typename
字面量来为对象定义名称。我们还将 __typename
字面量设置为 nullish
,这意味着 __typename
字段是可选的,如果存在,则必须为 "Cat"。
在上面的代码中,我们仍旧使用 __typename
字面量来为对象定义名称,但这次我们将 __typename
字面量设置为 "Cat",这意味着 __typename
字段是必须的,且必须为 "Cat",当使用 GraphQL interface
和 union
时,必填的 __typename
将非常有用。
使用 collectNames
在上面的代码中,我们使用 collectNames
函数来为对象定义名称。collectNames
函数接受一个对象,该对象的键是对象的名称,值是对象本身。
在上面的代码中,我们使用 collectNames
函数来为对象定义名称,并将返回的对象解构为 Cat
并导出。
使用 asObjectType
在上面的代码中,我们使用 asObjectType
函数创建一个元数据并将其传入 superRefine()
中来为对象定义名称。asObjectType
函数接受完整的 GraphQL 对象类型定义,并返回一个元数据。
添加更多元数据
通过 asObjectType
注册器,我们可以为对象添加更多元数据,例如 description
、deprecationReason
、extensions
等。
在上面的代码中,我们为 Cat
对象添加了一个 description
元数据,该元数据将在 GraphQL Schema 中呈现:
我们还可以使用 asField 函数为字段添加元数据,例如 description、type 等。
在上面的代码中,我们为 age
字段添加了 type
和 description
元数据,最终得到如下 GraphQL Schema:
声明接口
我们还可以使用 asObjectType
函数来声明接口,例如:
在上面的代码中,我们使用 asObjectType
函数创建了一个接口 Fruit
,并使用 interfaces
选项将 Orange
对象声明为 Fruit
接口的实现。
省略字段
我们还可以使用 asField
函数将 type
设置为 null
来省略字段,例如:
将得到如下 GraphQL Schema:
定义联合类型
使用 z.discriminatedUnion
我们推荐使用 z.discriminatedUnion
来定义联合类型,例如:
在上面的代码中,我们使用 z.discriminatedUnion
函数创建了一个联合类型。对于 Animal
来说,它通过 __typename
字段来区分具体的类型。
使用 z.union
我们还可以使用 z.union
来定义联合类型:
在上面的代码中,我们使用 z.union
函数创建了一个联合类型。对于 Animal
来说,我们通过 resolveType
函数来区分具体的类型。
在这里,如果一个动物它喜欢鱼,那么它就是一只猫,否则就是一只狗。
定义枚举类型
我们可以使用 z.enum
或 z.nativeEnum
定义枚举类型。
使用 z.enum
通常,我们更推荐使用 z.enum
来定义枚举类型,例如:
自定义类型映射
为了适应更多的 Zod 类型,我们可以拓展 GQLoom 为其添加更多的类型映射。
首先我们使用 ZodWeaver.config
来定义类型映射的配置。这里我们导入来自 graphql-scalars 的 GraphQLDateTime
、GraphQLJSON
和 GraphQLJSONObject
标量,当遇到 date
、any
和 record
类型时,我们将其映射到对应的 GraphQL 标量。
在编织 GraphQL Schema 时传入配置到 weave
函数中:
默认类型映射
下表列出了 GQLoom 中 Zod 类型与 GraphQL 类型之间的默认映射关系:
Zod 类型 | GraphQL 类型 |
---|---|
z.array() | GraphQLList |
z.string() | GraphQLString |
z.string().cuid() | GraphQLID |
z.string().cuid2() | GraphQLID |
z.string().ulid() | GraphQLID |
z.string().uuid() | GraphQLID |
z.literal("") | GraphQLString |
z.literal(false) | GraphQLBoolean |
z.literal(0) | GraphQLFloat |
z.number() | GraphQLFloat |
z.number().int() | GraphQLInt |
z.boolean() | GraphQLBoolean |
z.object() | GraphQLObjectType |
z.enum() | GraphQLEnumType |
z.nativeEnum() | GraphQLEnumType |
z.union() | GraphQLUnionType |
z.discriminatedUnion() | GraphQLUnionType |