{"content":{"title":"理解 GraphQL  101","body":">- 原文链接：https://thetshaped.dev/p/graphql-intro-101-part-2\r\n>- 译者：[AI翻译官](https://learnblockchain.cn/people/19584)，校对：[翻译小组](https://learnblockchain.cn/people/412)\r\n>- 本文永久链接：[learnblockchain.cn/article…](https://learnblockchain.cn/article/8817)\r\n    \r\n自从在 Facebook 创建以来，许多开发人员已经接受了 GraphQL 作为构建 API 的新且有前途的方式。\r\n\r\n我已经使用 GraphQL 超过 3.5 年了，对这项技术感到非常兴奋。然而，学习曲线很陡峭。这篇文章的目标是对 GraphQL 世界进行有意识的介绍。\r\n\r\n## 什么是GraphQL\r\n\r\n**GraphQL**是一种**现代 API 标准** - 一种**用于 API 的查询语言**。它通过允许客户端**请求确切所需的数据**来实现**声明式数据获取**。这使得 GraphQL 成为现代 Web 和移动应用程序的一个吸引人选择。\r\n\r\n**GraphQL 提供了一种更高效、更强大和更灵活的替代传统 REST API 的方式**。它是平台和语言**不绑定**的。然而，在 JavaScript / React 世界中最受欢迎。\r\n\r\n## 历史\r\n\r\n- **2012** - 由 Facebook（Meta）内部开始\r\n- **2015** - 公开源代码\r\n- **2018** - 移至由非营利性 Linux 基金会主办的新成立的 GraphQL 基金会\r\n- 开发了并行技术，例如：Falcor（Netlix）\r\n- **被顶级公司广泛使用** - Facebook（Meta）、GitHub、Airbnb、Netflix、Shopify、Twitter（X）等许多其他公司\r\n\r\n![](https://img.learnblockchain.cn/attachments/migrate/1721804307983)\r\n> 来源：https://2020.stateofjs.com/en-US/technologies/datalayer/\r\n\r\n## 如何开始的\r\n\r\nFacebook 有必要**优化其移动应用程序的数据加载**，因为它们需要在缓慢或不可靠的移动网络连接上高效运行。**数据传输最小化至关重要**。\r\n\r\n随着 Facebook 应用程序复杂性的增加，传统 REST API 的限制，如**过度获取和不足获取数据**变得越来越明显。用户界面需要更多**动态数据交互**。\r\n\r\n- **过度获取**：下载比必要的数据更多的数据\r\n- **不足获取**：端点未返回足够的正确信息；需要发送多个请求（n+1 请求问题）\r\n\r\nReact 和 GraphQL 之间的协同作用非常好。**React 的基于组件的架构与 GraphQL 的细粒度数据获取能力非常匹配**，使它们互补。\r\n\r\n## 使用案例\r\n\r\n- **移动应用程序**：移动应用程序受益于 GraphQL，因为它最小化了通过网络传输的数据量。\r\n- **复杂系统**：具有许多实体和关系的系统通常使用 GraphQL 在单个请求中获取相关数据。\r\n\r\n例如，我们通过 [GitHub 的 GraphQL API Explorer](https://docs.github.com/en/graphql/overview/explorer) 获取我的 GitHub 用户和拉取请求信息。请参见下面的屏幕截图。\r\n\r\n![](https://img.learnblockchain.cn/attachments/migrate/1721804308011)\r\n\r\n我们只需**一个请求**，如下面的屏幕截图所示。\r\n\r\n![](https://img.learnblockchain.cn/attachments/migrate/1721804308049)\r\n\r\n如果我们必须使用他们的 REST API，我们至少需要发出 2 个请求 - 获取用户信息，然后获取该用户的拉取请求。\r\n\r\n## 架构\r\n\r\n在高层次概述中，**服务器公开一个响应查询和变更的单个 HTTP 端点**。 \r\n\r\n![](https://img.learnblockchain.cn/attachments/migrate/1721804308053)\r\n> **注意：**这是对现代架构中如何使用 GraphQL 的简单概述。\r\n\r\n\r\n\r\n## GraphQL 的优点\r\n\r\n- **高效数据加载**\r\n  - 减少多个请求和数据过度获取的需求\r\n  - 客户端有权请求确切所需的数据\r\n- **强类型**\r\n  - 每个数据结构都与特定类型相关联，有助于验证查询\r\n  - 强类型模式定义了客户端<>服务器之间的明确合约。创建自我记录 API 变得更容易，从而改善开发人员体验。\r\n- **当产品发生变化时无需更改 API**\r\n\r\n## GraphQL 的不足\r\n\r\n- **复杂性** - 初始设置和学习曲线与 REST 相比可能较陡峭\r\n- **性能问题** - 复杂查询有时可能导致性能瓶颈，如果管理不当\r\n- 还有一些其他痛点，如错误处理、客户端缓存和文件上传，目前尚不完全清楚如何解决。\r\n\r\n\r\n\r\n## GraphQL 核心概念\r\n\r\n### 查询\r\n\r\n查询用于**读取或获取数据**。它们代表客户端请求从 GraphQL 服务器获取特定数据的方式。与 REST 不同，REST 中的多个端点返回固定的数据结构，**GraphQL 查询精确地检索客户端请求的数据**。\r\n\r\n客户端定义他们需要的数据的结构，从 GraphQL 模式中定义的类型和字段中进行选择。这种选择性查询有助于避免 REST API 中常见的过度获取和不足获取的问题。\r\n\r\n \r\n\r\n![](https://img.learnblockchain.cn/attachments/migrate/1721805187372)\r\n\r\n>  示例：GitHub 的 API。\r\n\r\n### Mutations (变更)\r\n\r\n\r\n\r\n变更是**我们在 GraphQL 中更改数据的方式**，如创建新数据，更新和删除现有数据。\r\n\r\n与查询在语法上类似，但变更不仅仅是获取数据，变更修改服务器端数据，并通常在变更后返回数据的新状态。\r\n\r\n\r\n![](https://img.learnblockchain.cn/attachments/migrate/1721805187519)\r\n> 示例：GitHub 的 API。\r\n\r\n\r\n### 模式定义语言（SDL）\r\n\r\n模式定义语言（SDL）是**用于编写 GraphQL 模式的语法**。它是人类可读的，用于定义**类型，查询，变更以及类型之间的关系**。\r\n\r\nSDL 用于定义对象，输入，接口，联合和枚举，这些是 GraphQL 模式的构建块。\r\n\r\n\r\n![](https://img.learnblockchain.cn/attachments/migrate/1721805187543)\r\n\r\n> 示例：GitHub 的 GraphQL API。略有简化。\r\n\r\n\r\n\r\n### GraphQL Schema(模式)\r\n\r\nGraphQL Schema 代表**客户端和服务器之间的契约**。它通过指定客户端如何获取和变更数据来定义 API 的功能。\r\n\r\n该模式作为一个关键的蓝图，指导查询和变更的结构。它告知 GraphQL 服务器在获取或操作数据时调用哪些函数，并确保仅执行有效的操作。\r\n\r\n \r\n\r\n![](https://img.learnblockchain.cn/attachments/migrate/1721805187539)\r\n\r\n> 示例：GitHub 的 GraphQL API。略有简化。\r\n\r\n\r\n\r\n### Resolvers (解析器)\r\n\r\n解析器是**处理模式中特定字段的获取或操作数据的服务器端函数**。**每个类型的每个字段都有一个解析器函数**。\r\n\r\n当接收到查询或变更时，解析器的工作是生成请求的数据并以客户端请求的格式返回。\r\n\r\n举个例子，假设我们在 GraphQL 模式中定义了以下查询：\r\n\r\n \r\n\r\n![](https://img.learnblockchain.cn/attachments/migrate/1721805187650)\r\n\r\n \r\n\r\n相应的解析器函数可能如下所示：\r\n\r\n \r\n\r\n![](https://img.learnblockchain.cn/attachments/migrate/1721805190072)\r\n\r\n\r\nGraphQL 服务器负责根据用户的查询和/或变更调用适当的解析器函数。\r\n\r\n注：在即将发布的文章中，我将撰写一个更详细的逐步指南，介绍如何实现自己的 GraphQL 服务器，其中解析器的用法将变得清晰。\r\n\r\n\r\n\r\n## 高层次架构\r\n\r\n接下来的三种架构代表了**GraphQL 的主要使用情况**，展示了在可以使用的上下文中的灵活性。\r\n\r\n### 简单架构\r\n\r\n带有连接数据库的 GraphQL 服务器。\r\n\r\n![](https://img.learnblockchain.cn/attachments/migrate/1721805190091)\r\n\r\n 这是一个标准的全新架构，其中一个 GraphQL 服务器连接到单个数据库。\r\n\r\n### 集成遗留系统\r\n\r\n集成现有系统的 GraphQL 层。\r\n\r\n \r\n\r\n![](https://img.learnblockchain.cn/attachments/migrate/1721805190345)\r\n\r\n\r\nGraphQL 允许你隐藏现有系统（如微服务，传统基础设施或第三方 API）的复杂性，将其放在单个 GraphQL 接口后面。\r\n\r\n### 混合架构\r\n\r\n\r\n\r\n连接数据库并集成现有系统的混合方法。\r\n\r\n \r\n\r\n![](https://img.learnblockchain.cn/attachments/migrate/1721805190564)\r\n\r\n这两种方法也可以结合使用，GraphQL 服务器既可以从单个数据库获取数据，也可以从现有系统获取数据。这样可以实现完全的灵活性，并将所有数据管理复杂性推到服务器端。\r\n\r\n\r\n\r\n## 小结\r\n\r\n\r\n\r\n在**GraphQL Intro 101**系列中，我们介绍了 GraphQL 的基础知识，从 GraphQL 是什么，为什么以及如何使用 GraphQL，到其核心概念和使用情况中的高级架构。\r\n\r\n重要的是要记住：\r\n\r\n> **GraphQL 只是一个规范。**\r\n\r\n这意味着 GraphQL 实际上不过是一份详细描述 GraphQL 服务器行为的长文档。\r\n\r\n我们还没有看到 GraphQL 服务器的任何实现细节以及其他概念，如订阅，片段，指令，联邦等。我将在即将发布的文章中涵盖它们，因为这些是更高级的概念，值得单独的文章。\r\n\r\n敬请关注 GraphQL 系列即将发布的文章，我们将深入探讨如何使用 Apollo Server 实现自己的 GraphQL 服务器。\r\n\r\n*   [https://graphql.org/learn/](https://graphql.org/learn/) - 优秀的文档\r\n\r\n*   [http://spec.graphql.org/](http://spec.graphql.org/) - 规范\r\n\r\n*   [https://www.howtographql.com/](https://www.howtographql.com/) - 免费开源教程\r\n\r\n*   [https://foundation.graphql.org/](https://foundation.graphql.org/) - GraphQL 基金会\r\n\r\n> 我是 [AI 翻译官](https://learnblockchain.cn/people/19584)，为大家转译优秀英文文章，如有翻译不通的地方，在[这里](https://github.com/lbc-team/Pioneer/blob/master/translations/8817.md)修改，还请包涵～"},"author":{"user":"https://learnblockchain.cn/people/21853","address":null},"history":"bafkreihf2qbot3wgpxpk5cc752tbacqted2j45r5hprd2wdwlprqgfd6ze","timestamp":1721806500,"version":1}