2、GraphQL核心概念:Schema、Query、Mutation、Subscription的定义与作用
好,咱们直接进入正题。
GraphQL 的核心,说白了就四个东西:Schema、Query、Mutation、Subscription。你把这四个搞明白了,GraphQL 就算入门了。我当年刚接触时,也觉得概念多,但用起来其实就那几招。
2.1 Schema:你的数据契约
Schema 是什么?我习惯把它理解成前后端之间的合同。你前端能查什么数据,后端能返回什么数据,全写在这份合同里。
举个例子,你在写一个用户列表功能。后端说:“我给你 id、name、email 这三个字段。” 那前端就只能拿这三个。多一个没有,少一个不行。这就是 Schema 的约束力。
核心要点:Schema 定义了数据的形状和类型。它是强类型的,每个字段都得有明确的类型。
来看一段典型的 Schema 定义:
type User {
id: ID!
name: String!
email: String!
posts: [Post!]!
}
type Post {
id: ID!
title: String!
content: String!
author: User!
}
注意那个感叹号 !,它表示这个字段不能为空。我在项目中遇到过好几次,前端没处理空值,结果页面直接崩了。嗯,从那以后我特别留意这个感叹号。
2.2 Query:查数据,就这么简单
Query 就是查数据用的。你想想看,REST API 里你要查用户,得调 /api/users,查文章得调 /api/posts。但在 GraphQL 里,你只需要一个 Query 入口。
Query 的定义长这样:
type Query {
users: [User!]!
user(id: ID!): User
posts: [Post!]!
}
前端发起查询时,可以这样写:
query GetUsers {
users {
id
name
email
}
}
你发现没?前端想要什么字段就写什么字段。不会多返回一个你不需要的字段。我记得有一次做移动端优化,接口返回的数据量太大,用 GraphQL 后,流量直接降了 40%。这就是按需查询的魅力。
小技巧:我建议每个 Query 都起个名字,比如 GetUsers、GetPostById。这样调试时一眼就能看出是哪个查询出了问题。
2.3 Mutation:改数据,有规矩
Mutation 是用来增删改数据的。为什么叫 Mutation 不叫 Update?因为 GraphQL 的设计哲学是:任何修改数据的操作,都应该显式地声明为 Mutation。
定义 Mutation 的语法和 Query 很像:
type Mutation {
createUser(name: String!, email: String!): User!
deleteUser(id: ID!): Boolean!
}
前端调用时:
mutation CreateUser($name: String!, $email: String!) {
createUser(name: $name, email: $email) {
id
name
email
}
}
这里有个坑,我曾经踩过:Mutation 执行完后,一定要返回修改后的数据。比如创建用户后,返回新用户的 id。这样前端才能更新本地状态,不用再发一次 Query。
注意:Mutation 是串行执行的。你连续发两个 Mutation,第二个会等第一个执行完。但 Query 是并行的,别搞混了。
2.4 Subscription:实时数据,像听广播
Subscription 是 GraphQL 里最酷的功能之一。它让前端可以订阅某个事件,后端有数据更新时,主动推给前端。
你想想看,聊天应用、实时通知、股票行情……这些场景用 Subscription 再合适不过了。
定义 Subscription:
type Subscription {
newPost: Post!
userUpdated(id: ID!): User!
}
前端订阅:
subscription OnNewPost {
newPost {
id
title
content
author {
name
}
}
}
一旦有人创建了新文章,后端就会把数据推过来。前端不用轮询,不用手动刷新。我个人觉得,这是 GraphQL 比 REST 强很多的地方。
实战建议:Subscription 底层通常用 WebSocket 实现。如果你项目里用 Apollo Client,它已经帮你封装好了。但要注意,Subscription 的连接数不能太多,否则服务器压力会很大。
2.5 四者关系速览
| 概念 | 作用 | 类比 REST | 执行方式 |
|---|---|---|---|
| Schema | 定义数据结构和类型 | API 文档 + 类型定义 | 静态定义 |
| Query | 查询数据(读) | GET 请求 | 并行执行 |
| Mutation | 修改数据(写) | POST/PUT/DELETE | 串行执行 |
| Subscription | 实时数据推送 | WebSocket | 长连接 |
2.6 避坑指南
最后,分享几个我实际项目中遇到的坑:
- Schema 别写太大。我见过一个项目,一个 Schema 文件 3000 行。后来拆成多个模块,用
extend type合并,清爽多了。 - Mutation 记得返回数据。不返回的话,前端还得再查一次,多一次网络开销。
- Subscription 别滥用。不是所有实时场景都需要 Subscription。比如用户列表,每 30 秒轮询一次就够了,没必要开长连接。
- 命名规范要统一。我习惯 Query 用
getXxx,Mutation 用createXxx、updateXxx、deleteXxx。团队里统一了,代码可读性会好很多。
嗯,这四个概念讲完了。说白了,Schema 是蓝图,Query 是查,Mutation 是改,Subscription 是实时监听。你把这四个搞明白,GraphQL 的基本功就算扎实了。
下一章,咱们会动手写一个完整的 Schema,到时候你就知道这些概念怎么落地了。