JSON Schema
JSON Schema 是一种声明性语言,用于标注和验证 JSON 文档的结构、约束条件及数据类型。它可帮助你实现 JSON 数据的标准化,并明确对 JSON 数据的预期要求。
安装
我们可以在项目中直接使用 JSON Schema,也可以使用 typebox 帮助我们构建 JSON Schema。
sh
npm i graphql @gqloom/core @gqloom/jsonsh
pnpm add graphql @gqloom/core @gqloom/jsonsh
yarn add graphql @gqloom/core @gqloom/jsonsh
bun add graphql @gqloom/core @gqloom/jsonsh
deno add npm:graphql npm:@gqloom/core npm:@gqloom/json定义简单标量
在 GQLoom 中,可以使用 jsonSilk函数 将 JSON Schema 作为丝线使用:
ts
import { jsonSilk } from "@gqloom/json"
const StringScalar = jsonSilk({ type: "string" })
const BooleanScalar = jsonSilk({ type: "boolean" })
const FloatScalar = jsonSilk({ type: "number" })
const IntScalar = jsonSilk({ type: "integer" })定义对象
在定义对象时,也需要使用 jsonSilk 函数包裹:
ts
import { jsonSilk } from "@gqloom/json"
const Cat = jsonSilk({
title: "Cat",
type: "object",
properties: {
name: { type: "string" },
age: { type: "integer" },
loveFish: { type: ["boolean", "null"] },
},
required: ["name", "age"],
})为对象命名
提示
命名在 GQLoom 中是可选的,GQLoom 将根据操作名称自动为对象命名。
但在大部分场景下,显式命名是更推荐的实践。
我们可以使用 JSON Schema 的 title 属性为对象命名,比如上面的示例代码;也可以使用 __typename 字面量来为对象命名:
ts
import { jsonSilk } from "@gqloom/json"
const Cat = jsonSilk({
type: "object",
properties: {
__typename: { const: "Cat" },
name: { type: "string" },
age: { type: "integer" },
loveFish: { type: ["boolean", "null"] },
},
required: ["name", "age"],
})定义联合类型
我们可以使用 JSON Schema 的 oneOf 属性来定义联合类型:
ts
import { jsonSilk } from "@gqloom/json"
const Cat = jsonSilk({
title: "Cat",
type: "object",
properties: {
__typename: { const: "Cat" },
name: { type: "string" },
loveFish: { type: "boolean" },
},
})
const Dog = jsonSilk({
title: "Dog",
type: "object",
properties: {
__typename: { const: "Dog" },
name: { type: "string" },
loveBone: { type: "boolean" },
},
})
const Animal = jsonSilk({
title: "Animal",
oneOf: [Cat, Dog],
})定义枚举类型
我们可以使用 JSON Schema 的 enum 属性来定义枚举类型:
ts
import { jsonSilk } from "@gqloom/json"
const Fruit = jsonSilk({
title: "Fruit",
description: "Some fruits you might like",
enum: ["apple", "banana", "orange"],
})自定义类型映射
为了适应更多的 JSON Schema 类型,我们可以拓展 GQLoom 为其添加更多的类型映射。
首先我们使用 JSONWeaver.config 来定义类型映射的配置。
这里我们导入来自 graphql-scalars 的 GraphQLDate 标量,当遇到 date 类型时,我们将其映射到对应的 GraphQL 标量。
ts
import { JSONWeaver } from "@gqloom/json"
import { GraphQLDate } from "graphql-scalars"
const jsonWeaverConfig = JSONWeaver.config({
presetGraphQLType: (schema) => {
if (typeof schema === "object" && schema.format === "date")
return GraphQLDate
},
})在编织 GraphQL Schema 时传入配置到 weave 函数中:
ts
import { weave } from "@gqloom/json"
export const schema = weave(jsonWeaverConfig, helloResolver)默认类型映射
下表列出了 GQLoom 中 JSON Schema 类型与 GraphQL 类型之间的默认映射关系:
| JSON Schema 属性 | GraphQL 类型 |
|---|---|
{"type": "string"} | GraphQLString |
{"type": "number"} | GraphQLFloat |
{"type": "integer"} | GraphQLInt |
{"type": "boolean"} | GraphQLBoolean |
{"type": "object"} | GraphQLObjectType |
{"type": "array"} | GraphQLList |
{"enum": [...]} | GraphQLEnumType |
{"oneOf": [...]} | GraphQLUnionType |
{"anyOf": [...]} | GraphQLUnionType |