GraphQL是一种面向API的开源查询语言,可通过一次API调用从多个来源获取数据。它还可作为服务器端运行时,利用现有数据处理查询。GraphQL既能提供完整的API数据描述,又能确保客户端仅获取所请求的数据,并让API更易于扩展和演进。

了解GraphQL

GraphQL在设计时充分考虑了灵活性、速度和开发者需求。借助GraphQL,开发者可以根据实际需要构建API,然后使用GraphQL规范确保这些API可供客户端正常使用。

GraphQL查询的一个核心理念是,返回的数据是可预测的。它不会返回冗余代码,而是仅返回请求的内容。这种声明式数据获取方式尤其适用于带宽有限的移动设备。使用GraphQL的应用也更加稳定、快速,因为请求和接收哪些数据由应用而非服务器控制。即使网络连接较慢,应用也能快速响应,因为单个请求可以一次返回多个所需项目。

在GraphQL简化数据的基础上,API按类型和字段而非端点进行组织。这意味着所有数据都可通过单一端点访问,使应用能够仅请求必要的数据。GraphQL可降低运维复杂性,适用于精简的API连接解决方案工作流。

简史

2012年,Meta(当时名为Facebook)需要一个数据获取API,其功能足以满足Facebook移动应用的需求。在Lee Byron的带领下,Facebook开发了GraphQL,旨在简化数据获取,尤其是从产品设计师和开发者的角度出发。GraphQL最初在Facebook内部使用,随后于2015年公开发布并开源。与许多其他开源项目的发展历程类似,GraphQL项目于2019年迁至其独立的GraphQL Foundation,并由Linux Foundation托管。

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中的一些关键术语包括:

  • 模式:由API开发人员创建,用于说明客户端可以查询哪些数据。模式由对象类型组成,对象类型定义客户端可以请求的内容,以及表示对象特征的字段。
  • 查询:查询会先根据架构进行验证,然后执行。如果未定义对象类型,GraphQL无法执行查询。
  • 解析器:在API执行过程中,系统会调用附加到各个架构字段的解析器函数来生成值。解析器是GraphQL架构中的关键组件。

GraphQL的一项独特功能是,响应会与查询的结构保持一致(查询本身由架构定义)。由于服务器响应的格式完全可预测,因此客户端解析起来更加简单。

设计

GraphQL采用层次结构,可反映对象之间的关系,因此非常适合层次化用户界面。它还具有强类型特性,即查询的每一层都与一种类型匹配,而这些类型又定义了一组字段。这与SQL类似,系统会在查询完成前显示说明性错误消息。

将解析器连接到数据源

解析器是将GraphQL字段、边、变更、查询和订阅连接到数据源(及微服务)的关键架构模块。

可通过本GraphQL 教程了解如何为 AWS 数据源构建解析器。

指定要获取的内容

GraphQL查询的一项独特之处在于响应会映射查询结构。查询返回的数据具有可预测性,因为其结构会与API请求的结构一致。当返回的数据结构遵循客户端查询时,服务器端的处理也会更加简单。

GraphQL 的优势

GraphQL的一大优势是可以通过扩展提供REST不具备的功能。GraphQL的其他优势包括:

建立单一事实来源

GraphQL schema为GraphQL应用程序建立单一事实来源,提供一个描述所有数据的主要位置。虽然GraphQL schema通常在服务器端定义,但客户端仍可根据该schema查询和写入数据。

避免过度获取

在REST架构中,过度获取数据很快就会成为问题:应用程序(后端)定义每个资源可用的数据,并在响应中返回全部数据,即使客户端(前端)只需要其中一个元素。GraphQL调用只需一次往返,即可向客户端提供所请求的数据,而不会过度获取。

改善客户端与服务器之间的通信

由于数据类型有严格定义,与REST相比,GraphQL中的客户端与服务器通信更加清晰。这种底层结构也意味着,调用GraphQL服务器不需要复杂的客户端。如需了解更多信息并查看实际代码,请阅读GraphQL官方页面上有关客户端和服务器的内容。

通过Federation实现可扩展性

API联合是一套设计原则和工具,可将有界上下文中的服务作为一致的API提供给用户,同时允许该上下文中的服务不受限制地演进。GraphQL提供了一种联合整个API的方法,使其能够在不破坏现有查询的情况下演进,并实现扩展。这种可扩展性正是许多企业采用GraphQL的原因之一。

内省

GraphQL的内省特性支持从GraphQL API中检索GraphQL架构。客户端还可以请求可用数据类型列表,非常适合自动生成文档,以及测试或检索多个微服务的架构。

GraphQL 的缺点

采用GraphQL有很多理由,但也需要注意一些缺点。例如,并非所有功能都能开箱即用,使用他人提供的API需要专用库。总体而言,与REST相比,GraphQL需要更强的工具支持。

与REST相比,GraphQL存在以下缺点。

学习曲线

对于习惯使用REST API的开发人员来说,GraphQL的学习曲线更陡。它还可能改变工作流程,使用GraphQL的API团队还必须编写易于维护的GraphQL模式。不过,如果从头开始学习,GraphQL可能比较容易掌握和使用,因为请求和响应采用相同的结构。

独特的API管理策略

GraphQL可能需要采用新的API管理策略,而REST API通常可以沿用现有的API管理模式。这一点需要重点考虑,因为新增API管理策略可能会增加总体成本。

复杂的缓存机制

与REST相比,GraphQL中的缓存并不那么直接。REST请求通常使用HTTP方法(GET、POST、PUT或DELETE)。标准GraphQL请求使用POST,无法在HTTP层缓存。GraphQL中的缓存也可能变得复杂,因为单一端点意味着同一个端点URL会产生多个不同且不可缓存的响应(有利于获取数据,但不利于缓存)。因此,服务器开发人员最终需要区分查询,即使每个查询都在同一对象中运行。尽管如此,许多GraphQL库都提供开箱即用的缓存机制。