GraphQL Schema
GraphQL Schema 是客户端与服务端共享的强类型 API 契约,规定可查询的类型、字段、参数、根操作与可空性边界。
GraphQL Schema
一句话定义
GraphQL Schema 是 API 的类型契约:它声明“客户端允许问什么、参数长什么样、服务端承诺返回什么形状”。
它描述 API,而不是数据库表结构。
为什么需要 Schema
REST 常把契约分散在 URL、HTTP 方法、DTO 和文档里;GraphQL 把可查询能力集中进一个类型系统,因此客户端可以在发送请求前知道字段是否存在、参数是否合法、返回值是否可能为空。
type User {
id: ID!
name: String!
age: Int
}
type Query {
user(id: ID!): User
}
这里表达了几个稳定事实:
User.id、User.name必须有值;age可以为空;- 客户端可以从根
Query查询user; user必须接收一个非空ID;- 查询结果本身可能找不到,因此
User没有!。
Schema 怎样成为前后端接口合同
在 REST 团队中,前端常通过 OpenAPI / Swagger / Apifox 等文档知道:
URL
HTTP method
request body
response DTO
GraphQL 中,这一层的核心真值就是 Schema 本身。
最常见的声明方式是 SDL(Schema Definition Language):
type Query {
user(id: ID!): User
}
type User {
id: ID!
name: String!
}
也可以采用 code-first:先用某种语言的类型/构造器定义 Schema,再由框架生成等价的 GraphQL Schema。无论来源是哪种,真正提供给客户端验证和执行的仍是一棵 GraphQL 类型系统。
GraphQL 还定义了 introspection。客户端或工具可以查询 Schema 自己,得到:
有哪些 Query / Mutation / Subscription
有哪些 Object / Enum / Union / Interface
字段叫什么、是什么类型
参数是什么类型
哪些位置允许 null
因此常见团队工作流是:
Backend Schema
↓ publish / introspection / schema registry
GraphQL tooling
├─ 自动文档
├─ IDE 自动补全
├─ operation validation
└─ TypeScript codegen
↓
Frontend Query / Mutation
所以 GraphQL 的接口文档不只是给人阅读的说明书,而可以成为 机器可读取、可校验、可生成代码的 executable contract。
实际生产环境是否开放公网 introspection 是部署与安全策略问题;即使关闭公开 introspection,团队仍可以通过构建产物、Schema 文件或 registry 向前端发布同一份合同。
核心模型
Scalar
GraphQL 内置常见标量:Int、Float、String、Boolean、ID。
标量是查询树的叶子;客户端最终选择的普通字段通常落到标量。
Object
type Diagnosis {
id: ID!
summary: String!
author: User!
}
对象字段可以继续指向另一个对象,因此查询可以沿关系展开。
List 与 Nullability
[Diagnosis!]!
从里向外读:
Diagnosis!:列表元素不能是null;[...]!:列表本身不能是null。
不要把 ! 理解成 TypeScript 的非空断言;它是服务端公开契约的一部分。
Root Types
type Query { ... }
type Mutation { ... }
type Subscription { ... }
它们定义客户端进入整个数据图的入口:读取、写入与实时订阅。
Schema 的验证边界
Schema 很擅长验证:
字段是否存在
参数是否缺失
String / Int / Float 等基础类型是否匹配
nullability 是否满足
输入对象 shape 是否符合声明
但默认:
email: String!
age: Int!
并不能自动证明:
email 是合法邮箱格式
age >= 18
score 在 0..100
这些通常还需要自定义 Scalar / Directive,或更常见地在 application boundary 使用 Zod 等 runtime validation,再由 Service / Domain 处理业务规则。
因此:
GraphQL Type Validation
≠ 完整 Runtime Validation
≠ Business Validation
≠ Database Constraint
Schema 不负责什么
Schema 能证明“请求形状合法”,但不能证明:
- 当前用户有权限读取该字段;
- 数据库一定存在对应记录;
- resolver 不会报错;
- 返回内容符合业务事实;
- 查询成本一定合理;
String!一定符合邮箱、URL 等业务格式;Int!一定满足业务范围约束。
这些属于 runtime validation、resolver、授权、业务规则、数据库约束和执行治理。
最重要的心智模型
GraphQL Schema
↓ 约束
客户端 Operation
↓ 执行
Resolver
↓
Service / Repository / Database
Schema 是公开边界,Resolver 才把这个边界连接到真实业务实现。
常见误解
- Schema = 数据库 schema:不是。GraphQL Schema 面向 API,可以组合、隐藏或重塑数据库数据。
- Schema = 一份手写接口说明文档:不只是。它是 GraphQL Server 真正用于验证和执行 operation 的机器合同。
- 有类型就没有运行时错误:不是。类型只能覆盖契约中的一部分运行时问题。
String!就能验证 Email:不能,除非额外定义语义验证机制。- 对象之间有关系就一定 JOIN:不是。如何取数由 resolver 决定,也正因此可能产生 N+1。
Related notes
- 所属 MOC: GraphQL MOC
- 上层概念: GraphQL
- 完整案例: GraphQL 一次请求的端到端执行
- 下一步: GraphQL Query 与 Resolver 的执行链
- 对比: GraphQL vs REST