Zod
Zod is a TypeScript-first schema declaration and validation library. I'm using the term "schema" to broadly refer to any data type, from a simple string to a complex nested object.
Zod is designed to be as developer-friendly as possible. The goal is to eliminate duplicative type declarations. With Zod, you declare a validator once and Zod will automatically infer the static TypeScript type. It's easy to compose simpler types into complex data structures.
@gqloom/zod
provides integration of GQLoom with Zod to weave Zod Schema into GraphQL Schema.
Installation
Defining simple scalars
In GQLoom, you can directly use Zod Schema as silk.
Weave
To ensure that GQLoom
correctly weaves the Zod Schema into the GraphQL Schema, we need to add the ZodWeaver
from @gqloom/zod
when using the weave
function.
Defining Objects
We can define objects using Zod and use them as silk to use:
Names and more data
Defining names for objects
In GQLoom
we have multiple ways to define names for objects.
Using __typename
literal
In the code above, we used the __typename
literal to define the name for the object. We also set the __typename
literal to nullish
, which means that the __typename
field is optional, and if it exists, it must be “Cat”.
In the code above we are still using the __typename
literal to define the name for the object, but this time we are setting the __typename
literal to “Cat”, which means that the __typename
field is mandatory and must be “Cat”, which will be very useful when using the GraphQL interface
and union
The required __typename
will be very useful when using GraphQL interface
and union
.
Using collectNames
In the above code, we are using the collectNames
function to define names for objects. The collectNames
function accepts an object whose key is the name of the object and whose value is the object itself.
In the code above, we use the collectNames
function to define the names for the objects and deconstruct the returned objects into Cat
and export them.
Using asObjectType
In the code above, we used the asObjectType
function to create a metadata and pass it into superRefine()
to define a name for the object. The asObjectType
function takes the complete GraphQL object type definition and returns a metadata.
Add more metadata
With the asObjectType
function, we can add more data to the object, such as description
, deprecationReason
, extensions
and so on.
In the above code, we have added a description
metadata to the Cat
object which will be presented in the GraphQL Schema:
We can also use the asField function to add metadata to a field, such as description, type, and so on.
In the above code, we added type
and description
metadata to the age
field and ended up with the following GraphQL Schema:
Declaring Interfaces
We can also use the asObjectType
function to declare interfaces, for example:
In the above code, we created an interface Fruit
using the asObjectType
function and declared the Orange
object as an implementation of the Fruit
interface using the interfaces
option.
Omitting Fields
We can also omit fields by setting type
to null
using the asField
function, for example:
The following GraphQL Schema will be generated:
Defining Union Types
Using z.discriminatedUnion
We recommend using z.discriminatedUnion
to define union types, for example:
In the above code, we have created a union type using the z.discriminatedUnion
function. In the case of Animal
, it distinguishes the specific type by the __typename
field.
Using z.union
We can also use z.union
to define union types:
In the above code, we have created a union type using the z.union
function. For Animal
, we use the resolveType
function to differentiate between specific types.
Here, if an animal likes fish, then it is a cat, otherwise it is a dog.
Defining Enumeration Types
We can define enum types using z.enum
or z.nativeEnum
.
Using z.enum
In general, we prefer to use z.enum
to define enumeration types, for example:
Using z.nativeEnum
We can also use z.nativeEnum
to define enumeration types, for example:
Customize Type Mappings
To accommodate more Zod types, we can extend GQLoom to add more type mappings to it.
First we use ZodWeaver.config
to define the type mapping configuration. Here we import the GraphQLDateTime
, GraphQLJSON
and GraphQLJSONObject
scalars from graphql-scalars and map them to the matching GraphQL scalars when encountering the date
, any
and record
types.
Configurations are passed into the weave
function when weaving the GraphQL Schema:
Default Type Mappings
The following table lists the default mappings between Zod types and GraphQL types in GQLoom:
Zod types | GraphQL types |
---|---|
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) | GraphQLInt |
z.number() | GraphQLFloat |
z.number().int() | GraphQLFloat |
z.boolean() | GraphQLBoolean |
z.object() | GraphQLObjectType |
z.enum() | GraphQLEnumType |
z.nativeEnum() | GraphQLEnumType |
z.union() | GraphQLUnionType |
z.discriminatedUnion() | GraphQLUnionType |