GraphQL入门指南

Schema定义、Query查询、Mutation变更及GraphQL vs REST深度对比

📅 2026年4月6日 · 阅读约10分钟 · GraphQLAPI后端开发

GraphQL是Facebook于2015年开源的API查询语言和运行时,它提供了一种更灵活、更高效的数据获取方式。与REST不同,GraphQL让客户端能够精确指定需要的数据,避免了数据获取不足或过多的问题。如今,GraphQL已被GitHub、Shopify、Twitter等大型平台广泛采用。本指南将帮助你从零理解GraphQL的核心概念。

一、GraphQL是什么

GraphQL不是一种数据库技术,也不是一种编程语言,而是一个API查询语言运行时。它定义了一套类型系统,客户端可以用这个类型系统来精确请求所需的数据。

GraphQL的核心优势:

二、Schema — 类型系统

Schema是GraphQL API的核心,它定义了所有可用的数据类型、查询和变更操作。使用Schema Definition Language(SDL)编写。

# 定义类型
type User {
  id: ID!
  name: String!
  email: String!
  age: Int
  posts: [Post!]!
  createdAt: String!
}

type Post {
  id: ID!
  title: String!
  content: String!
  author: User!
  tags: [String!]!
  likes: Int!
}

# 定义输入类型
type CreateUserInput {
  name: String!
  email: String!
  age: Int
}

# 定义查询入口
type Query {
  user(id: ID!): User
  users(limit: Int, offset: Int): [User!]!
  posts(userId: ID): [Post!]!
  search(query: String!): [Post!]!
}

# 定义变更入口
type Mutation {
  createUser(input: CreateUserInput!): User!
  updateUser(id: ID!, name: String, email: String): User!
  deleteUser(id: ID!): Boolean!
  createPost(title: String!, content: String!): Post!
  likePost(id: ID!): Post!
}

# 定义订阅入口
type Subscription {
  newPost: Post!
  userUpdated(id: ID!): User!
}
💡 类型标记:String! 中的 ! 表示该字段非空(Non-Null)。[Post!]! 表示非空的Post数组,数组中每个元素也不能为null。

三、Query — 数据查询

Query用于读取数据,是GraphQL最常用的操作类型。

# 基本查询
query {
  user(id: "123") {
    name
    email
    posts {
      title
      likes
    }
  }
}

# 带变量和参数
query GetUsers($limit: Int = 10) {
  users(limit: $limit) {
    id
    name
    email
  }
}

# 使用别名(同类型字段多次查询)
query {
  admin: users(role: "admin") {
    id
    name
  }
  editors: users(role: "editor") {
    id
    name
  }
}

# 片段复用
query {
  user(id: "123") {
    ...UserFields
    posts {
      ...PostFields
    }
  }
}
fragment UserFields on User {
  id
  name
  email
}
fragment PostFields on Post {
  title
  likes
  createdAt
}

四、Mutation — 数据变更

Mutation用于修改数据(创建、更新、删除)。按照惯例,Mutation按顺序执行(不同于Query的并行执行)。

# 创建用户
mutation {
  createUser(input: {
    name: "张三",
    email: "zhangsan@example.com",
    age: 28
  }) {
    id
    name
    email
  }
}

# 同时执行多个变更
mutation UpdateUserAndPost($userId: ID!, $postId: ID!, $title: String!) {
  updateUser(id: $userId, name: "李四") {
    id
    name
  }
  updatePost(id: $postId, title: $title) {
    id
    title
  }
}

五、Subscription — 实时订阅

# 订阅新文章
subscription {
  newPost {
    id
    title
    author {
      name
    }
  }
}

Subscription基于WebSocket实现,当服务端有新数据时自动推送给客户端。适用于实时通知、聊天应用、协作编辑等场景。

六、GraphQL vs REST 对比

维度RESTGraphQL
端点数量多个(每个资源一个)单个(/graphql)
数据获取固定结构,可能过多或不足客户端按需指定
关联数据多次请求或over-fetching一次请求嵌套获取
版本控制URL路径版本(v1, v2)字段演进,无需版本号
类型安全依赖文档或OpenAPI内置强类型系统
缓存HTTP缓存天然支持需要额外配置
学习曲线较低中等
错误处理HTTP状态码200 + errors字段
实时能力需要SSE/WebSocket内置Subscription

七、生态与工具

八、何时选择GraphQL

推荐使用GraphQL:数据模型复杂、多个客户端需要不同数据、需要实时功能、微服务聚合层。

推荐继续使用REST:简单CRUD应用、需要HTTP缓存、团队对REST更熟悉、带宽敏感的移动端场景。

🛠️ 开发者工具箱

访问 ToolSnap 获取JSON格式化、代码美化、编码转换等在线开发者工具。

常见问题(FAQ)

GraphQL和REST有什么区别?

REST有多个端点,每个端点返回固定结构;GraphQL只有一个端点,客户端可以精确指定需要的数据字段。REST可能需要多次请求获取关联数据,GraphQL一次请求即可获取所有需要的数据。

GraphQL适合什么场景?

GraphQL适合:复杂嵌套数据结构、多客户端需要不同数据字段、实时数据订阅、微服务API网关聚合。不适合简单的CRUD应用或需要HTTP缓存优化的场景。

什么是GraphQL Schema?

Schema是GraphQL的类型系统定义,描述了所有可用的数据类型、查询和变更操作。它是API的"合同",客户端和服务端通过Schema达成数据约定。

GraphQL如何处理错误?

GraphQL请求始终返回200状态码,错误信息放在响应的errors字段中。每个错误包含message、locations、path等信息。