Weave

In GQLoom, the weave function is used to weave multiple Resolvers or Silks into a single GraphQL Schema.

The weave function can take resolver, silk, weaver configuration, global middleware

Weaving resolvers

The most common usage is to weave multiple resolvers together, for example:

import { weave } from '@gqloom/core'; export const schema = weave(HelloResolver, CatResolver);

Weaving a single silk

Sometimes we need to weave a single silk woven into a GraphQL Schema, for example:

valibot
zod
import { resolver, query, field, valibotSilk, weave } from '@gqloom/core' import { ValibotWeaver } from '@gqloom/valibot' import * as v from "valibot" const Dog = v.object({ __typename: v.nullish(v.literal("Dog")), name: v.string(), age: v.number(), }) export const schema = weave(ValibotWeaver, HelloResolver, CatResolver, Dog);

Weaver configuration

Input type naming conversion

In GraphQL, objects are recognized as type and input.

When using GQLoom, we usually only use the object type, and behind the scenes GQLoom will automatically convert the object type to the input type. The advantage of this is that we can use the object type directly to define input parameters without having to define the input type manually. However, when we use the same object type for both type and input, it will not be woven into GraphQL Schema due to naming conflict.

Let's look at an example:

valibot
zod
import { resolver, mutation, weave } from '@gqloom/core' import { ValibotWeaver } from '@gqloom/valibot' import * as v from "valibot" const Cat = v.object({ __typename: v.nullish(v.literal("Cat")), name: v.string(), birthDate: v.string(), }) const CatResolver = resolver({ createCat: mutation(Cat, { input: { data: Cat, }, resolve: ({ data }) => data, }), }) export const schema = weave(ValibotWeaver, CatResolver);

In the above code, we defined a Cat object and used it for type and input. But when we try to weave CatResolver into the GraphQL Schema, an error is thrown with a duplicate Cat name:

Error: Schema must contain uniquely named types but contains multiple types named "Cat".

To solve this problem, we need to specify a different name for the input type. We can do this using the getInputObjectName option in the SchemaWeaver.config configuration:

valibot
zod
import { resolver, mutation, weave, SchemaWeaver } from '@gqloom/core' import { ValibotWeaver } from '@gqloom/valibot' import * as v from "valibot" const Cat = v.object({ __typename: v.nullish(v.literal("Cat")), name: v.string(), birthDate: v.string(), }) const CatResolver = resolver({ createCat: mutation(Cat, { input: { data: Cat, }, resolve: ({ data }) => data, }), }) export const schema = weave( CatResolver, ValibotWeaver, SchemaWeaver.config({ getInputObjectName: (name) => `${name}Input` }) )

Thus, Cat objects will be converted to CatInput types, thus avoiding naming conflicts.

The above CatResolver will weave the following GraphQL Schema:

type Mutation { createCat(data: CatInput!): Cat! } type Cat { name: String! birthDate: String! } input CatInput { name: String! birthDate: String! }

Global middleware

import { weave } from '@gqloom/core'; import { logger } from './middlewares'; export const schema = weave(HelloResolver, CatResolver, logger)

See more about middleware usage in middleware section.