GraphQL 是一种开源 API 查询语言,能够在一次 API 调用中从多个来源获取数据。它还是一种服务器端运行时,用于对现有数据执行查询。GraphQL 强调为客户端仅仅提供所请求的数据,并且同时还提供完整的 API 数据描述,从而可以简化 API 的扩展和演变。
GraphQL 简介
GraphQL 在设计时充分考虑了灵活性、速度和开发人员。借助 GraphQL,开发人员能够以他们认为合适的方式构建 API,然后利用 GraphQL 规范来确保 API 可供客户端使用。
GraphQL 查询的一个重要理念是返回的数据是可预测的。返回的正是所请求的内容,而不是多余的代码串。这种声明式数据获取在带宽有限的移动设备上特别有用。使用 GraphQL 的应用快速稳定,因为控制请求和接收的数据的是这些应用,而不是服务器。即使在网络连接速度较慢的情况下,它们的速度也很快,因为单个请求可同时返回多个请求的条目。
基于 GraphQL 将数据进行了简化,API 被按照类型和字段而非端点进行划分。这意味着能够在单个端点上访问所有数据,从而使得应用只需查询必要的内容。由于 GraphQL 可降低操作复杂性,它非常适合精简的 API 互联解决方案的工作流。
简史
2012 年,Meta(当时的 Facebook)需要一个可支持其 Facebook 移动应用的强大的数据获取型 API。在 Lee Byron 的领导下,Facebook 开发了 GraphQL 以简化数据获取——特别是从产品设计师和开发人员的角度来看。GraphQL 首先在 Facebook 内部使用,后于 2015 年公开发布并开源。按照许多其他开源项目的发展轨迹,2019 年 GraphQL 项目被转移到由 Linux 基金会托管的 GraphQL 基金会。
GraphQL 被设计为 REST 架构的替代方案。标准 REST API 需要通过单独的 HTTP GET
请求从多个 URL 加载信息。借助 GraphQL API,所有数据均可通过单个 POST
请求进行检索。虽然 REST 和 GraphQL 都返回 JSON 格式的响应,但 GraphQL 侧重于精简和整合数据。
GraphQL 的工作原理
GraphQL 支持细粒度的数据请求,并加强了客户端对所发送信息的控制。客户端以 POST
请求的形式发送 GraphQL 查询,然后服务器会返回 JSON 格式的响应。GraphQL 不需要特定的应用架构,可部署在多种环境(包括集成式开发环境 [IDE])中,并能够与现有 API 管理工具结合使用,或者在现有 REST API 之上使用。
GraphQL 中的一些关键术语包括:
- 模式(Schema)——由 API 开发人员创建,显示客户端可查询的数据;模式由对象(object)类型组成,对象类型定义了客户端可请求的信息以及代表对象特征的字段。
- 查询(Query)——查询经过验证后,根据模式予以执行。如果不定义对象类型,GraphQL 将无法执行查询。
- 解析器(Resolver)——附加到每个模式字段的解析器函数会在 API 执行中被调用以生成值。解析器是 GraphQL 的关键架构组件。
GraphQL 的独特之处在于返回的响应可以映射查询的结构(由模式定义)。这简化了客户端的解析工作,因为服务器响应的格式完全可预测。
设计
GraphQL 的层次性决定了对象之间的关系,并使其在分层用户界面中非常好用。另外 GraphQL 也是强类型的,这意味着每个查询级别都与某个数据类型相匹配。然后,这些类型会定义一组字段。这一点与 SQL 类似——会在完成查询前显示描述性错误消息。
将解析器连接到数据源
解析器是将 GraphQL 字段(field)、边缘(edge)、更新(mutation)、查询(query)及订阅(subscription)连接到数据源(和微服务)的关键架构模块。
您可通过 GraphQL 教程了解如何为 AWS 数据源构建解析器。
指定要获取的信息
GraphQL 查询的独特之处在于映射响应。由于您知道它将与来自 API 请求的格式相匹配,查询返回的数据就变得可预测了。当返回的数据格式遵循客户端查询的格式时,服务器端就被简化了。
GraphQL 的优点
GraphQL 的一大优势是,可通过扩展来提供 REST 中没有的特性。GraphQL 还具有以下优点。
设置单一信源
GraphQL 模式会在 GraphQL 应用中设置单一信源,它提供了一个可以了解所有数据的地方。虽然一般会在服务器端定义 GraphQL 的模式,但客户端仍可根据模式来查询和写入数据。
无过度获取
在 REST 架构中,过度获取很快就会成为问题:应用(后端)定义每个资源可用的数据,并在其响应中返回所有数据,即使客户端(前端)需要的只是其中的一个数据元素。而 GraphQL 的调用是单程的,只为客户端提供所请求的数据,不会过度提供多余数据。
改进客户端和服务器之间的通信
由于数据类型经过了明确定义,因此在 GraphQL 中,客户端和服务器之间的通信比在 REST 中更清晰。该底层结构还意味着不需要使用复杂的客户端来调用 GraphQL 服务器。如欲了解更多信息并查看运行代码,请参考 GraphQL 官方页面上有关客户端和服务器的介绍。
可通过 Federation 进行扩展
API Federation(API 联邦)提供了一套设计原则和工具,便于在定义好的上下文中将多个 service 作为一个具有一致性的 API 暴露给用户,同时也允许该上下文中的 service 不受限制地演变。GraphQL 支持在不中断先前查询的情况下,邦联整个 API 进行演变,从而实现扩展。这种可扩展性是许多企业争相采用 GraphQL 的原因之一。
自省
GraphQL 的 introspective(自省)属性支持从 GraphQL API 中检索 GraphQL 模式。客户端还可以请求可用数据类型列表——这十分适合文档和测试的自动生成,以及在多个微服务中检索模式的情况。
GraphQL 的缺点
虽然采用 GraphQL 的原因有很多,但它也有一些值得注意的缺点。举例来说,它并非完全开箱即用,需要使用特殊的库才能使用别人的 API。而且,总的来说,与 REST 相比,GraphQL 需要更多的工具支持。
与 REST 相比,GraphQL 具有以下缺点。
学习曲线
对于习惯使用 REST API 的开发人员来说,GraphQL 更难掌握。它还改变了工作流——使用 GraphQL 的 API 团队还必须编写可维护的 GraphQL 模式(schema)。不过,如果从头学起,GraphQL 也很容易学习和使用,因为请求和响应具有相同的结构。
独特的 API 管理策略
GraphQL 可能需要新的 API 管理策略,而 REST API 通常适合现有的 API 管理模式。这是一个重要的考虑因素,因为新增 API 管理策略会增加总支出。
复杂的缓存
GraphQL 中的缓存机制不如在 REST 中简单。在 REST 中,请求通常使用 HTTP 方法(GET
、POST
、PUT
或 DELETE
)。标准的 GraphQL 请求使用的是 POST 方法,其在 HTTP 层面不可缓存。
GraphQL 中的缓存变得复杂的原因还包括只有一个端点,因为这意味着该端点的 URL 会生成多个不同的不可缓存响应(这有利于获取数据,但不利于缓存)。即使所有的请求都使用同样的对象结构,服务器端的开发人员还是需要使用不同的查询语句。
不过,好在许多 GraphQL 库都提供可开箱即用的缓存机制。