丝线(Silk)
丝线(Silk)是 GraphQL 纺织机的基本原料,它同时反应 GraphQL 类型和 TypeScript 类型。 在开发时,我们使用现有的模式库的 Schema 作为丝线,最终 GQLoom 会将丝线编织进 GraphQL Schema。
简单的标量丝线
我们可以使用 silk 函数创建一个简单的标量丝线:
ts
import { silk } from "@gqloom/core"
import { GraphQLString, GraphQLInt, GraphQLNonNull } from "graphql"
const StringSilk = silk(GraphQLString)
const IntSilk = silk(GraphQLInt)
const NonNullStringSilk = silk(new GraphQLNonNull(GraphQLString))
const NonNullStringSilk1 = silk.nonNull(StringSilk)对象丝线
我们可以直接使用 graphql.js 构造 GraphQL 对象:
ts
import { silk } from "@gqloom/core"
import {
GraphQLObjectType,
GraphQLNonNull,
GraphQLString,
GraphQLInt,
} from "graphql"
interface ICat {
name: string
age: number
}
const Cat = silk(
new GraphQLObjectType<ICat>({
name: "Cat",
fields: {
name: { type: new GraphQLNonNull(GraphQLString) },
age: { type: new GraphQLNonNull(GraphQLInt) },
},
})
)在上面的代码中:我们定义了一个 ICat 接口,并使用 silk 函数定义了一个名为 Cat 的丝线。 其中,silk 函数接受 ICat 作为泛型参数,还接受一个 GraphQLObjectType 实例用来阐述 Cat 在 GraphQL 中的详细结构。
Cat 在 GraphQL 中将呈现为:
graphql
type Cat {
name: String!
age: Int!
}你可能注意到了,使用 graphql.js 来创建丝线需要同时声明 ICat 接口和 GraphQLObjectType,也就是说,我们为 Cat 创建了两份定义。 重复的定义让代码损失了简洁性,也增加了维护成本。
使用 Schema 库创建丝线
好在,我们有像 Valibot、Zod 这样的 Schema 库,它们创建的 Schema 将携带 TypeScript 类型,并在运行时仍然携带类型。 GQLoom 可以直接使用这些 Schema 作为丝线,而不需要重复定义。
GQLoom 目前已经集成来自以下库的 Schema:
另外,还有一些库可借由 JSON Schema 作为丝线,如 TypeBox、ArkType、Effect Schema 等。
ts
import * as v from "valibot"
const StringSilk = v.string()
const BooleanSilk = v.boolean()
const Cat = v.object({
__typename: v.literal("Cat"),
name: v.string(),
age: v.number(),
})我们可以直接将 Valibot Schema 作为丝线使用,但不要忘记在编织时添加来自 @gqloom/valibot 的 ValibotWeaver。
ts
import { weave } from "@gqloom/core"
import { ValibotWeaver } from "@gqloom/valibot"
export const schema = weave(ValibotWeaver, ...resolvers)