Skip to content
GQLoom

编织(Weave)

在 GQLoom 中,weave 函数用于将多个解析器(Resolver)或丝线(Silk)编织到一张 GraphQL Schema 中。

weave 函数可以接收解析器丝线、编织器配置、全局中间件

编织解析器

最常见的用法是将多个解析器编织到一起,例如:

ts
import { weave } from '@gqloom/core';

export const schema = weave(helloResolver, catResolver);

编织单独丝线

有时候,我们需要将一个单独的丝线编织到 GraphQL Schema 中,例如:

ts
import { 
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
);
ts
import { 
weave
} from '@gqloom/core'
import {
ZodWeaver
} from '@gqloom/zod'
import * as
z
from "zod"
const
Dog
=
z
.
object
({
__typename
:
z
.
literal
("Dog").
nullish
(),
name
:
z
.
string
(),
age
:
z
.
number
(),
}) export const
schema
=
weave
(
ZodWeaver
,
helloResolver
,
catResolver
,
Dog
);

编织器配置

输入类型命名转换

在 GraphQL 中,对象分为 typeinput 类型。

而使用 GQLoom 时,我们一般只使用 object 类型,在幕后 GQLoom 会自动将 object 类型转换为 input 类型。 这样做的好处是我们可以直接使用 object 类型来定义输入参数,而无需手动定义 input 类型。 但是当我们将同一个 object 类型同时用于 typeinput 时,将因为命名冲突而无法编织成 GraphQL Schema。

让我们来看一个例子:

ts
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
);
ts
import { 
resolver
,
mutation
,
weave
} from '@gqloom/zod'
import {
ZodWeaver
} from '@gqloom/zod'
import * as
z
from "zod"
const
Cat
=
z
.
object
({
__typename
:
z
.
literal
("Cat").
nullish
(),
name
:
z
.
string
(),
birthDate
:
z
.
string
(),
}) const
catResolver
=
resolver
({
createCat
:
mutation
(
Cat
, {
input
: {
data
:
Cat
,
},
resolve
: ({
data
}) =>
data
,
}), }) export const
schema
=
weave
(
ZodWeaver
,
catResolver
);

在上面的代码中,我们定义了一个 Cat 对象,并将其用于 typeinput。但是当我们尝试将 catResolver 编织到 GraphQL Schema 中时,会抛出一个错误,提示 Cat 名称重复:

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

要解决这个问题,我们需要为 input 类型指定一个不同的名称。我们可以使用 SchemaWeaver.config 配置中的 getInputObjectName 选项来实现这一点:

ts
import { 
resolver
,
mutation
,
weave
,
GraphQLSchemaLoom
} 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
,
GraphQLSchemaLoom
.
config
({
getInputObjectName
: (
name
) => `${
name
}Input` })
)
ts
import { 
resolver
,
mutation
,
weave
,
GraphQLSchemaLoom
} from '@gqloom/core'
import * as
z
from "zod"
const
Cat
=
z
.
object
({
__typename
:
z
.
literal
("Cat").
nullish
(),
name
:
z
.
string
(),
birthDate
:
z
.
string
(),
}) const
catResolver
=
resolver
({
createCat
:
mutation
(
Cat
, {
input
: {
data
:
Cat
,
},
resolve
: ({
data
}) =>
data
,
}), }) export const
schema
=
weave
(
catResolver
,
GraphQLSchemaLoom
.
config
({
getInputObjectName
: (
name
) => `${
name
}Input` })
)

如此一来,Cat 对象将被转换为 CatInput 类型,从而避免了命名冲突。

以上的 catResolver 将编织得到如下 GraphQL Schema:

graphql
type Mutation {
  createCat(data: CatInput!): Cat!
}

type Cat {
  name: String!
  birthDate: String!
}

input CatInput {
  name: String!
  birthDate: String!
}

全局中间件

ts
import { weave } from '@gqloom/core';
import { logger } from './middlewares';

export const schema = weave(helloResolver, catResolver, logger)

中间件章节中查看更多关于中间件的用法。