GraphQL - 简介
GraphQL - 简介
Section titled “GraphQL - 简介”GraphQL 是一种开源的查询语言(query language),用于你的 API,也是一个服务器端运行时环境(server-side runtime),用于通过你现有数据执行这些查询。GraphQL 由 Facebook 于 2012 年内部开发,并于 2015 年公开发布,它提供了一种比传统 REST API 更高效、强大且灵活的替代方案。
GraphQL 没有定义多个返回固定数据结构(就像在 REST 中那样)的僵化端点(endpoint),而是暴露一个单一的端点,允许客户端精确地请求他们需要的数据,不多不少。
为何选择 GraphQL?相比 REST 的关键优势
Section titled “为何选择 GraphQL?相比 REST 的关键优势”虽然 REST API 一直以来表现良好,但它们经常带来挑战,特别是在数据需求不断变化的复杂应用中。GraphQL 解决了其中的许多问题:
1. 按需索取,不多不少(避免过度获取 - Over-fetching)
Section titled “1. 按需索取,不多不少(避免过度获取 - Over-fetching)”REST 中的问题: 典型的 REST 端点(例如,/api/users/123)可能会返回一个包含许多字段的大型用户对象,即使客户端只需要用户的姓名和电子邮件。这称为过度获取(over-fetching)—— 下载了不必要的数据,浪费了带宽并可能降低应用速度。
GraphQL 解决方案: 客户端发送一个查询,精确指定他们想要的字段。服务器只响应那些数据。
考虑获取学生的 ID 和名字:
# GraphQL Queryquery GetStudentName { student(id: "S1001") { id firstName }}响应将只包含 id 和 firstName,即使底层的 Student 类型有许多其他字段(如 lastName、collegeName 等)。
// GraphQL Response{ "data": { "student": { "id": "S1001", "firstName": "Mohtashim" } }}这使得应用更快、更高效,特别是在移动网络上。
2. 一次请求获取多个资源(避免数据不足获取 - Under-fetching)
Section titled “2. 一次请求获取多个资源(避免数据不足获取 - Under-fetching)”REST 中的问题: 为了获取相关数据(例如,用户及其帖子,或学生及其大学详情),客户端通常需要对不同端点进行多次往返请求(例如,先请求 /api/users/123,然后请求 /api/users/123/posts)。这称为数据不足获取(under-fetching)—— 单个端点提供的数据不足,导致多次网络请求和增加延迟(即“N+1 问题”)。
GraphQL 解决方案: GraphQL 查询可以在一次请求中遍历相关的对象图。客户端可以高效地获取复杂的对象关系图。
获取学生的详细信息及其关联的大学信息:
# GraphQL Queryquery GetStudentAndCollege { student(id: "S1001") { id firstName lastName college { # Traverse to the related college object 遍历到相关的大学对象 name location } }}响应会一次性包含所有请求的嵌套数据:
// GraphQL Response{ "data": { "student": { "id": "S1001", "firstName": "Mohtashim", "lastName": "Mohammad", "college": { "name": "CUSAT", "location": "Kerala" } } }}这大大减少了客户端所需的网络请求数量。
3. 强类型和内省
Section titled “3. 强类型和内省”GraphQL API 是强类型的。 服务器使用 GraphQL Schema Definition Language (SDL) 定义一个 schema(模式),指定所有可用的数据类型、字段、查询(query)和变更(mutation)。这个类型系统充当客户端和服务器之间的契约。
- 可预测的结果: 客户端确切知道预期的数据类型。
- 早期错误检测: 无效的查询(请求不存在的字段、错误的参数类型)在执行前由服务器捕获。
- 改进的开发者体验: 支持强大的开发者工具。
- 内省(Introspection): 客户端可以查询 schema 本身以了解 API 的能力(例如,哪些查询可用,一个对象有哪些字段)。这允许自动生成文档和客户端代码。
Schema 示例片段:
type Student { id: ID! # ID is a specific scalar type, ! means non-nullable ID 是一种特定的标量类型,! 表示不可为空 firstName: String lastName: String college: College # Field linking to another object type 链接到另一个对象类型的字段}
type College { id: ID! name: String! location: String}
type Query { student(id: ID!): Student # Query to fetch a student by ID 按 ID 获取学生的查询 students: [Student] # Query to fetch a list of students 获取学生列表的查询}4. 无需版本控制即可演进 API
Section titled “4. 无需版本控制即可演进 API”REST 中的问题: 从 REST 端点添加或删除字段通常需要进行版本控制(例如,/api/v1/users,/api/v2/users)以避免破坏现有客户端。
GraphQL 解决方案: 由于客户端指定他们需要的确切字段,可以在不影响现有客户端的情况下向 schema 添加新字段(它们只是不会请求新字段)。可以在 schema 中标记已废弃(deprecated)的字段,给客户端在删除之前迁移的时间。
- Schema: 定义 API 能力的蓝图。
- Queries: 读取操作,用于获取数据。
- Mutations: 写入操作,用于创建、更新或删除数据。
- Subscriptions: 实时操作,接收由服务器推送的数据更新(通常通过 WebSockets)。
- Types: 在 schema 中定义的数据结构(Scalars、Objects、Enums 等)。
- Resolvers: 服务器端函数,为 schema 字段提供数据。
本教程将引导你学习这些概念,让你能够有效地构建和使用 GraphQL API。