首席技术官办公室报告

GraphQL 的作用和影响

  • 分享至 Facebook
  • 分享到X
  • 分享至 Linkedin
  • 分享至电子邮件
  • 通过 AddThis 分享
拉杰什·纳拉亚南
审阅者及贡献者: OCTO 团队及其他人员。

F5 首席技术官办公室意见

GraphQL 已成为一种现代而高效的 API 开发方法,超越了传统 REST API 的限制。 虽然 REST 自 Web 早期以来就被广泛使用,但 GraphQL 为开发人员提供了全新的视角和更大的控制力。 使用 GraphQL,开发人员可以定义强类型模式,使客户端能够精确地请求所需的数据。 通过消除数据的过度获取和不足,GraphQL 优化了性能并有助于创建具有复杂数据查询和数据建模要求的现代交互式 Web应用。

然而,我们承认 GraphQL 并非没有挑战。 本文深入探讨了与 GraphQL 采用相关的安全问题和学习曲线。 我们探索真实案例研究,描述成功实施 GraphQL 的知名公司所获得的好处。

此外,我们介绍了自己对 GraphQL 的研究,分享了我们的经验和发现。 我们概述了 GraphQL 的简短入门,将其与 REST 进行了比较,并深入研究了它所解决的挑战。 还讨论了安全考虑因素,以帮助组织做出明智的决策。 我们的研究揭示了 GraphQL 的变革潜力。 我们展示了如何简化测试管理套件软件架构,从而通过 GraphQL 使隐藏在 JSON 对象中的暴露数据量增长了 300% 以上。

总之,我们强烈建议正在努力扩展、优化或运营 REST API 基础设施的企业将 GraphQL 视为可行的解决方案。 我们的见解为那些踏上 GraphQL 之旅的人们提供了实用指导,使他们能够利用其优势并有效地克服挑战。

GraphQL 入门

为什么选择 GRAPHQL?

REST API 的局限性推动了对新 API 技术方法的需求。

基于 REST(表述性状态转移)的方法最初是作为一组用于设计 Web API 的架构原则提出的。 随着 Web 2.0 的出现,REST 在 2000 年代和 2010 年代不断发展,成为比其他技术(如通用对象请求代理架构 (CORBA))更好的实现面向服务架构 (SOA) 的方法。

随着移动设备的普及,客户数量不断增长,对精确数据的需求也随之增加。 然而,基于 REST 的 API 通常会导致数据获取过多或过少,从而导致效率低下。 这种方法(以 Facebook 等应用程序为例)通常需要为一次更新进行大量 REST API 调用,这会增加网络流量并影响性能和用户体验。

GraphQL 专门设计用于解决这些限制,它提供了强类型模式和更有效的数据查询方式。 这使其非常适合需要特定数据来优化网络带宽的用例。 此外,GraphQL 的模式自省能力可以提供更好的文档和工具。 虽然 REST 的更标准化实现可能会带来一些竞争,但 GraphQL 的独特功能和优势使其成为分布式和数据密集型现代应用架构的引人注目的选择。

图 1 展示了 REST 和 GraphQL 实现方式的拓扑差异。 正如REST API 与 GraphQL中所述,“GraphQL 和 REST API 之间的主要区别在于 GraphQL 是一种查询语言,而 REST 是一种基于网络的软件的架构概念。” 

图 1: REST 与 GraphQL。 改编自 Rest API vs. GraphQL

META 开发 GRAPHQL 的动机

Meta 于 2012 年创建了 GraphQL(2015 年开源),以提高其移动应用程序的性能和灵活性。 在 GraphQL 之前,Meta 的移动应用程序是使用 RESTful API 和本机代码的组合构建的,这使得难以处理应用程序需要支持的各种设备、屏幕尺寸和网络条件。 

他们面临的主要挑战之一是 RESTful API 通常会返回错误数量的数据 —— 有时太多,有时太少。 当 API 返回移动应用程序不需要的大量数据时,会导致加载时间变慢和性能不佳。 当 API 返回的数据太少时,移动应用程序需要向不同的端点发出多个请求来获取所需的所有数据,这会增加流程的延迟和复杂性。

Meta 开发了 GraphQL,因此任何应用程序都可以在单个请求中仅请求所需的数据。 这使得优化移动应用程序和后端服务之间的数据传输成为可能,从而缩短加载时间并提高性能。 此外,GraphQL 的强类型和自文档功能使开发人员更容易理解和使用 API。 

GRAPHQL 优势

GraphQL 提供了强大的数据检索和操作功能,与传统 API 方法相比具有显著的优势。 

强类型架构

GraphQL 具有强类型架构,可确保清晰准确地定义可从 API 查询的数据类型和结构。假设我们有一个包含书籍、作者和出版商的图书馆的 API。 

a) GraphQL模式: 在 GraphQL 中,强类型模式如下图 2 所示: 

图 2: GraphQL 架构示例

GraphQL 中的强类型模式通过启用输入验证、防止数据过度获取和获取不足、提供清晰的文档和工具支持、促进版本控制以及协助授权和访问控制,提供了与安全相关的好处。 这些功能通过降低常见漏洞的风险并确保正确的数据处理和访问权限管理增强 API 安全性。

在所示的示例中(图 2),该模式定义了书籍、作者和出版商的数据类型及其相互关系。 该模式是强类型的,这意味着每个字段都有特定的数据类型,并且客户端可以轻松自省模式以发现可用的字段及其类型。

b) REST模式: 在 REST 中,模式定义将是松散类型的,如下图 3 所示: 

图 3: REST 架构示例

这些端点返回代表书籍、作者和出版商的 JSON 对象,但模式本身并未明确定义,而是留给程序员的技能和解释。 客户必须依靠文档来了解数据的结构。

超越 REST

GraphQL 已经不再只是 REST 的更好替代品,而且有可能成为企业考虑更好数据策略的首选方法。 除了解决 REST 的局限性之外,还有其他几个原因使得 GraphQL 演变为一种新的 API 设计方法。 虽然表格(图 4)可以显示出 GraphQL 相对于 REST 的优势,但 GraphQL 最好被视为对互联网和不同应用的发展的响应,而不是对 REST 本身问题的识别的响应。

属性 图形查询语言 休息

灵活的数据建模

GraphQL 允许开发人员轻松定义和改进 API 以满足不断变化的需求。

客户端可以使用查询语言精确指定他们需要的数据,从而实现更加灵活和高效的数据检索过程。

服务器通常定义返回预定义数据结构的固定端点。

客户端对于响应的形状和结构的控制有限,经常导致数据获取过多或不足。

REST 缺乏 GraphQL 提供的对数据检索和组合的细粒度控制。

批量查询

GraphQL 允许将多个查询组合成一个请求,这可以显著减少客户端和服务器之间的往返次数并提高性能。

Rest 没有将多个查询批处理为单个请求的内置机制。 每个 REST 请求通常对应一个资源或端点。 一些 REST 框架或扩展可能提供了将多个请求捆绑在一起的方法,但不像 GraphQL 那样是原生的或标准化的

键入查询和响应

客户端可以指定其所需的精确数据,服务器可以仅使用所请求的数据进行响应,从而减少过度获取和获取不足。 此外,GraphQL 是强类型的,有助于防止错误并改善工具支持。

在查询和响应中,类型并不是强制的。 数据的结构和格式通常由服务器预定义,客户端必须相应地解释和处理数据。 这会导致类型安全性降低。

与前端框架集成

GraphQL 旨在与 React 和 Vue 等前端框架配合良好,从而更轻松地构建现代交互式 Web应用。 GraphQL 拥有专用的库和工具,可实现无缝集成

虽然 REST 可以与前端框架一起使用,但集成可能需要更多的手动工作和自定义实现。 虽然有第三方库,但 REST 并没有提供与特定前端框架(如 React 或 Vue)集成的标准化方式。

基于图的查询

GraphQL 允许在单个请求中进行跨越多个资源和关系的复杂查询,从而更容易获取构建复杂用户界面所需的数据。

REST 通常遵循以资源为中心的方法,其中每个端点代表一个特定的资源或实体。 它本身并不提供在单个请求中跨多个资源或关系查询数据的机制。

表现

GraphQL 能够精确地仅请求所需数据,从而实现更高效的数据检索并提高性能。

由于客户端对响应结构的控制有限,REST API 可能会遭受数据过度获取或数据获取不足的问题。 这会影响性能,特别是当 API 返回过多或不必要的数据时。

开发人员生产力

GraphQL 的自文档特性和自省功能减少了对大量文档的需求,并促进了对数据模型的更好地理解。 强类型模式和查询验证促进共享理解并尽早发现错误。 GraphQL 具有直观的查询语言和更容易的学习曲线,有助于开发团队更好地入职和知识转移。

由于客户端和服务器之间缺乏标准化的契约,部落知识受到影响。 REST API 通常依赖于非正式文档或因不同实现而变化的约定。 缺乏共同的理解会导致团队内部出现不一致和知识差距。 这就要求在团队中工作时间较长的开发人员必须花费宝贵的时间来培训团队成员,而不是专注于业务问题。 这种对个人进行文档记录的依赖导致了部落知识的分散,使得所有团队成员难以全面了解 API 的功能和数据结构。

API 版本控制

GraphQL 在版本控制方面的固有优势在于能够弃用即将被删除的字段,从而让客户端开发人员有时间进行调整。 类似于 REST API 的版本控制仍然是可能的。

弃用字段并不是 REST 固有的功能。 客户端开发人员需要确保他们使用的是正确版本的 API。

图 4: GraphQL 相对于 REST 的优势

GRAPHQL 面临的挑战

虽然 GraphQL 比传统的 RESTful API 提供了许多优势,但使用它也存在一些挑战。 常见的挑战包括:

  1. 学习曲线: 由于大多数开发人员更熟悉 REST,因此计划采用 GraphQL 的组织需要预留时间让他们的团队学习如何有效地使用它。 GraphQL 需要一种不同的思维方式来构建和使用 API,并且采用它可能需要改变底层应用架构。 开发人员可能需要学习新的概念,例如模式、解析器和类型,以及新的工具和库。 使用 GraphQL,客户端可以更好地控制他们可以访问的数据,这使得保护 API 变得更加困难。 输入验证、身份验证和授权等技术可能需要以与 RESTful API 不同的方式应用。
  2. 缓存: 使用 GraphQL 时缓存可能会更加复杂,因为客户端每次查询时可能会请求不同的数据,这使得缓存和重用响应变得更加困难。
  3. 表现: 虽然 GraphQL 允许客户端仅请求他们需要的数据,但它也可以支持更复杂、资源密集型的查询。 GraphQL API 可能存在性能问题,尤其是在查询大型数据集或发出大量并发请求时。 开发人员需要实施一些策略,例如限制查询深度或确保客户端仅被授权访问所需的特定数据。
  4. 错误处理: GraphQL 可以使错误处理更加复杂,因为错误可能作为响应的一部分返回,而不是作为单独的 HTTP 状态代码返回。
  5. 测试: 使用 GraphQL 进行测试面临着挑战,因为查询很复杂、缺乏标准化测试方法、模式演变以及运行时的查询验证。 开发人员需要投入时间寻找合适的测试框架和工具来应对这些挑战。 开发人员需要通过选择合适的工具并考虑模式演变来确保全面的测试覆盖范围,以有效地测试 GraphQL API 并确保其功能和稳定性。
  6. 监控: 由于查询的复杂性、缺乏标准化的日志记录和指标以及潜在的性能问题,监控 GraphQL API 可能具有挑战性。 GraphQL 查询的动态特性使得预测和监控请求数据的结构和大小变得更加困难。 缺乏针对 GraphQL API 的标准化监控工具,使得很难深入了解 GraphQL 查询性能、错误跟踪和 API 健康状况。 开发人员需要采用专门的监控工具和实践来处理 GraphQL 的独特特性,确保高效的性能和可靠的运行。 

GraphQL 使用模式

GraphQL 是一个功能强大的工具,可用于广泛的应用,从构建 API 到支持移动应用程序。 它的灵活性和统一数据源的能力使其非常适合各种不同的使用模式。

  1. 构建高效的 API : GraphQL 的主要用途之一是构建可供 Web 和移动应用使用的 API。 GraphQL 提供了一种灵活而强大的方式来定义和访问数据,使其非常适合构建需要支持广泛客户端和用例的 API。
  2. 数据获取和处理: GraphQL 可用于从各种来源获取和处理数据,包括数据库、云服务和其他 API。 通过提供访问数据的统一方式,GraphQL 可以帮助简化构建和维护数据驱动应用的过程。
  3. 实时用例: GraphQL 非常适合实时用例,因为客户端可以订阅特定数据的更新并在数据发生变化时接收通知。 这可用于聊天、直播、实时仪表板等应用。
  4. 微服务: GraphQL 可用于构建灵活、松散耦合的架构,允许不同的微服务以一致且定义明确的方式相互通信。
  5. 后端到前端: GraphQL 可用于构建后端前端 (BFF) 架构,让不同的前端客户端能够以一致且高效的方式访问数据和服务。
  6. 移动开发: GraphQL 可用于支持移动应用程序,通过提供一种以一致且有效的方式访问数据和服务的方法,而不受平台或设备的限制。 

行业 GraphQL 采用经验(案例研究)

我们需要 GraphQL 的动机很明显,如以下行业部署所示:

Netflix

Netflix 通过两部分博客系列总结了他们 2020 年的 GraphQL 之旅,对于任何 GraphQL 从业者来说,这都是必读之作。 他们展示的案例研究是Studio Edge 系统采用他们的工作室 API 并针对 GraphQL 进行重新架构。 Netflix 的 Studio API 被其内容团队用来管理和监控电视节目和电影的制作、后期制作和发行。 该 API 提供对大量数据的访问,包括有关标题、人才信息等的元数据。

最初,Studio API 是使用传统的 RESTful 架构构建的,其端点以 JSON 格式返回数据。 然而,随着 API 的增长和访问它的客户端数量的增加,显然需要一个更有效的解决方案。

Netflix 开始探索将 GraphQL 作为 Studio API 的潜在解决方案。他们首先为 Studio API 构建了一个精选图表。他们确定了几个主要优点,包括能够减少网络使用量、简化数据访问并通过允许客户端仅请求所需的数据来提高性能。

在为 Studio API 采用 GraphQL 时,Netflix 也面临一些独特的挑战,特别是在管理模式的复杂性以及确保客户端只能访问他们被授权查看的数据方面。

为了应对这些挑战,Netflix 开发了一种名为“Netflix GraphQL Federation”的定制解决方案,它使用 Apollo Federation 规范将 Studio API 模式拆分为更小、更易于管理的部分。 他们还实施了一个管理权限和访问控制的系统,这使得他们能够限制客户端对模式某些部分的访问。

他们还在博客中发布了其 API 架构的演变,从 Monolith 到 Federated Gateway。 图 5 是根据他们博客里的图片改编的。

图 5: API 架构的演变(改编自 Netflix)

我们认为还缺少另一种方法,这种方法可能在行业中很流行,但尚未正式化。

可以将图 5 中的网关聚合层和联合网关组合起来,如下所示:

图 6: F5 不断发展的 API 架构,包括临时 GraphQL 网关参与者 

每个齿轮图标本质上代表一个短暂的、联合的 GraphQL 实例(又名网关参与者),可以在边缘实时实例化(甚至基于每个事务),即在拓扑上靠近客户端并通过安全的 API 传输连接到微服务。 这种组合本质上用分布式网关参与者取代了网关聚合层或联合层,从而结合了两种功能的最佳特性。 我们将此称为分布式 GraphQL 网关参与者架构,如图 7 所示。

图 7: 分布式 GraphQL 网关参与者

其他早期采用者

贝宝

PayPal 自 2016 年起开始使用 GraphQL2018当他们将其作为 Checkout 应用程序的一部分时。他们对 REST 的主要担忧与 Meta 的类似,是其设计原则并未针对 Web 和移动应用程序及其用户进行优化。 客户端应用从客户端到服务器进行多次往返,大约需要 700 毫秒来获取数据。 这导致渲染时间变慢、用户失望并降低转化率。 对于结账应用程序,PayPal 发现用户界面 (UI) 开发人员花费不到三分之一的时间来构建 UI,而剩余的时间则花在研究如何获取和处理数据上。

PayPal 工程团队考虑的其他技术是编排 API 和 Bulk REST。 构建编排 API 将导致过度获取和客户端与服务器耦合。 PayPal 得出的结论是,随着时间的推移,这种方法可能会导致 API 变得沉重、笨拙,并且只能用于多种用途。 他们的 Bulk REST 实验也失败了。 虽然它使工程团队无需调整编排 API,但却要求他们的客户对 API 的工作方式有深入的了解。

PayPal 首次使用 GraphQL 构建新产品是将 PayPal Checkout 集成到应用程序中的移动 SDK。 在评估 GraphQL 的一周内,工程团队决定将其用于他们的新产品。 尽管 API 尚未准备好,他们仍然能够提前完成产品,而且几乎不需要任何 PayPal 特定的知识。 开发人员能够快速构建高效且用户友好的应用程序,说服工程团队在其技术堆栈中完全采用 GraphQL。 

星巴克

星巴克聘请第三方开发他们的渐进式 Web 应用程序(PWA)。

该团队的任务是创建一个能够高效、有效地适应复杂业务逻辑的订购系统。 由于客户能够个性化他们的订单,开发团队必须确保系统能够容纳多个独特业务逻辑实例,在正确的时间将正确的数据发送到正确的地点。

GraphQL 使团队能够创建具有服务器端缓存和渲染功能的高效 API,以改进离线功能。 该团队还使用 React 来融入动画,创造出动态且引人注目的用户体验。

F5 的 GraphQL

F5 首席技术官办公室的目标是了解如何在 F5 生态系统中使用 GraphQL。 我们有两个正在进行的项目正在探索 GraphQL 的使用。

改善数据模型和可见性

F5 提供的测试管理套件(TMS) 使客户能够测试自己系统的端点或客户端,并查看它们是人类还是机器人。

这是一个面向内部的项目,旨在帮助简化 TMS 软件开发和测试。 主要目标是提取现有 SQL 数据库中的 JSON 数据,转换为图形数据,并实现用于查询的 GraphQL API。

这是必要的,因为当前数据库带来了挑战,包括因将元数据作为 JSON 对象存储在表格数据库中而导致的“JSON- blob 问题”。 解析和处理这些对象本质上是昂贵且低效的。 此外,由于 JSON-blob 的图形特性,它包含有价值的数据,可以进一步改善 F5 的产品和安全性。 通过转换到有向图数据库,可以使用有向关系有效地解析和管理 JSON-blob,从而优化数据传输和利用率。 

图 8: F5 TMS GraphQL 项目范围

结果令人鼓舞。 通过识别 TMS 关系数据库中哪些表具有 JSON blob,我们确定移动到 GraphDB 并使用 GraphQL 可以多倍提高我们对系统的可见性。 

图 9: 实施选择

图 9 显示了该项目可能的演变或实施选择。 每一个选择都有其自身的含义。

选项 1 对 UI 的影响最小,因为客户端不需要改变。 混合模式(如选项 1 或 2)可能根据情况发挥良好作用,尤其是在 JSON 对象的列数量较少的情况下。 除此之外,每个 JSON 的派生模式也会很小。

但是在规划时,我们意识到 JSON 对象需要存储在 SQL 数据库的其他列中的上下文。 每个 JSON 对象中存储的模式的大小也相当大。 这会增加维护代码库的工作量。 因此,经过仔细考虑,我们决定重新构建应用以支持 GraphQL 和 Neo4J,如选项 3 所示。

CLOUDGRAPH 集成

CloudGraph 是适用于 AWS、Azure、GCP 和 Kubernetes (K8s) 的免费开源通用 GraphQL API 和云安全态势管理 (CSPM) 工具。 该项目的目标是利用 CloudGraph 构建一个“CloudGraph 插件”(图 10),以便 F5 分布式云(F5XC)数据显示在其上,从而更好地查看使用 F5 分布式云连接的云资源。

我们的目标是与 CloudGraph 集成以深入了解该技术并为 F5XC 数据构建未来的 CloudGraph 集成、洞察和 GraphQL API。

图 10: CloudGraph 与 F5 分布式云集成

将自定义 F5XC 提供程序集成到 CloudGraph 平台并使用该平台的创建关系功能后,我们将更好地了解使用 F5XC 连接的云资源及其与其他云的关系。 然后,我们可以针对同一租户跨多个云的资源生成复杂的查询。 这将使我们能够为利益相关者提供全面的 F5XC 概述,并探索 CloudGraph 的更深层次集成,以获得额外的 GraphQL 插件和与 F5 及其客户相关的云操作的定制见解。

基于上述举措,我们最初的探索与前面案例研究中概述的经验一致。

GraphQL 安全问题

关于 GraphQL 在安全性方面优于 REST 的最初看法已被推翻,因为 GraphQL 与任何其他技术一样,如果实施不当,也会带来自身的风险。 重要的是要认识到 GraphQL 本质上并不比其他技术更安全。 正确实施和遵守最佳实践对于确保 GraphQL API 的安全至关重要。 通过消除这种误解,我们可以以现实的理解来对待 GraphQL 的安全考虑因素,并采取适当的措施来减轻任何潜在的风险。

自省攻击

GraphQL 为开发人员提供了一个强大的工具,称为自省,允许他们请求有关 GraphQL 服务使用的模式的信息。 该工具使开发人员能够了解服务及其结构。 然而,自省也存在风险。 在生产 GraphQL 服务中启用自省意味着也可以访问模式内的敏感信息。 这带来了巨大的风险,因为恶意用户可以利用内省来获取敏感数据并可能造成危害。 此外,自省使这些用户能够轻松识别潜在的有害操作,因为他们可以查看整个模式并确定要执行哪些查询。 这种泄漏的后果可能是灾难性的,具体取决于模式的性质及其所包含的数据。

缓解措施: 减轻自省风险的一种解决方案是使用各种框架在生产 API 中禁用它。 通过禁用自省,开发人员将失去它提供的一些便捷功能。 但是,为了恢复其可用性,开发人员可以使用 GraphOS 等工具注册生产 API 的 GraphQL 模式。 这使得他们能够保留对架构及其信息的受控访问。

SQL 注入

SQL 注入是一种被广泛认可和普遍存在的攻击,其风险包括从数据操纵到完全删除数据库。 这种直接的攻击利用了字符串连接,允许攻击者在输入中插入可执行代码,授予对数据库的未授权访问并实现恶意更改。 有趣的是,这种攻击媒介不仅限于 SQL 数据库,还会影响 Neo4j 等图形数据库。 Neo4j 采用 Cypher 查询语言,它类似于 SQL 并继承了其漏洞。 这种攻击被称为 Cypher 注入,它利用了相似性,但也受益于现有解决方案,而不需要新的发明。

缓解措施: 对策包括清理用户输入以检测和防止漏洞利用,并使用参数化从直接查询创建中抽象用户输入。 这些措施有效地减轻了注入攻击的风险。 在 GraphQL 实现中解决这个安全问题至关重要,但幸运的是,已经有众所周知且易于实现的解决方案。 

REST 代理 API 攻击

在 REST API 之上分层 GraphQL API 可能会导致服务器端请求伪造 (SSRF) 漏洞。 攻击者可以通过修改通过 GraphQL 代理发送到 REST API 的参数来利用此漏洞。 如果两个 API 都没有验证特定调用的参数,攻击者就会获得对后端系统的控制权。 例如,在 GraphQL 查询中将“/delete”附加到用户 ID 后可能会导致在传递到 REST API 时意外删除数据。

缓解措施: 虽然此漏洞是一个合理的担忧,但可以通过在 GraphQL 模式中定义类型并在将参数发送到外部 API 或服务之前彻底验证参数来有效解决。 值得注意的是,此漏洞以及与 GraphQL 相关的其他漏洞源于实施问题,而不是 GraphQL 本身固有的问题。 尽管 GraphQL 这项技术前景广阔,但当人们因为短期心态而误用它时,就会出现此类问题。

批量攻击

身份验证漏洞是各种系统(包括 GraphQL)中普遍存在的攻击媒介。 GraphQL 能够在单个请求中发送多个查询或变异,这使其容易受到涉及暴力破解方法的批处理攻击。

第一类攻击涉及暴力破解登录密码。 攻击者发送包含登录凭证对的大量变异的请求。 由于 GraphQL 允许在一个请求中进行多次变异,因此此攻击会绕过速率限制检查,并通过暴力破解密码来创建会话。

第二种攻击的操作方式类似,但目标是一种流行的双因素身份验证 (2FA),即一次性密码 (OTP)。 单个请求通过多个变体发送,每个变体包含与不同 OTP 变体配对的有效登录凭证。 如果任何突变包含正确的 OTP,则请求将被验证,并且将建立会话。

缓解措施: 解决这些漏洞需要采取综合方法,因为没有万无一失的解决方案。 开发人员通过采用安全编码实践和强调业务逻辑的视角发挥着至关重要的作用。 在Web服务器端,实施限制登录尝试和验证用户输入等措施至关重要。 此外,应特别注意扫描多个变异的请求,因为合法的登录尝试通常不涉及多个变异。

拒绝服务攻击

这些攻击涉及用过多的流量压垮 GraphQL 服务,使其无法处理来自合法用户的请求并可能导致服务器崩溃。 DoS 攻击可以通过递归 GraphQL 查询或发送大型查询请求来执行。

在递归查询场景中,攻击者利用 GraphQL 模式定义的循环特性。 例如,如果模式包括作者和书籍类型,攻击者可以循环重复查询作者和书籍,用递归调用压垮服务器并破坏其运行。

或者,攻击者可以发出从数据库请求大量数据的查询。 例如,查询可以检索许多作者及其所有相关书籍。 如此大规模的数据请求可能会严重减慢系统速度甚至崩溃

缓解措施: 有几种解决方案可以缓解这个问题。 第一种方法是设置查询超时,阻止用户发出超过指定持续时间的请求。 然而,这可能无法完全解决问题,因为损害仍可能在规定的时间内发生。 另一个解决方案是强制限制查询深度和复杂性。 超出指定深度或复杂性(偏离模式定义)的查询将被拒绝。 最后,实施用户限制可能会很有效。 如果用户发送大量或连续的请求,则会暂时拒绝他们对服务器的访问,直到服务器准备好处理其他请求。

GraphQL 部署模式

如图所示,GraphQL 有几种部署模式,每种模式都有自己的一套权衡和考虑因素。 一些最常见的模式包括:

整体部署

这是部署 GraphQL API 最简单、最常见的模式。在单片部署中,GraphQL 服务器、数据库和任何其他必要的服务都作为一个单元一起部署。 这可以使使用 GraphQL 变得容易,但随着应用的增长,扩展和维护会变得困难。 

图 11: 简单的整体结构

组合巨石

组合单体是指使用单体和微服务组合构建单体应用的架构,其中 GraphQL 充当 API 层(图 12)。 在这种模式下,应用不是将整个系统分解为单独的微服务,而是最初开发为单独的整体式应用程序,它封装了所有业务逻辑和数据访问层。 

图 12: 组合式整体

在这个单体结构中,GraphQL 被实现为 API 层,允许客户端从不同的底层微服务请求和检索数据。 这意味着,虽然从部署角度来看应用仍然是单片的,但它利用 GraphQL 作为一种手段来组合来自各种服务的数据并以灵活高效的方式将其呈现给客户端。

此模式具有简化开发和部署、利用 GraphQL 强大的查询和数据获取功能等优势。 它允许开发人员逐步采用微服务架构,同时仍然受益于 GraphQL 提供的灵活性和易用性。 

联合子图

GraphQL 部署模式中的联合图涉及将多个 GraphQL 服务(称为子图)组合成单个统一的 GraphQL 模式。 每个子图代表一个单独的域或微服务,具有自己的数据和功能。 该架构使用中央网关,根据请求的字段将客户端查询路由到适当的子图。 通过联合这些子图,开发人员可以创建一个有凝聚力的图,客户端可以在不同的服务之间无缝查询和遍历。

图 13: 联邦子图

这种方法促进了服务的模块化、可扩展性和独立开发,从而提高了构建 GraphQL API 的性能和灵活性。 联合子图(图 13)提供了一种强大的方式来组合来自各种服务的数据并创建分布式、可扩展的架构。

混合图

GraphQL 部署模式中的混合图(图 14)通过拼接技术将联合子图和非联合模式结合在一起。 这种方法使组织能够将现有的 GraphQL API 或传统系统与联合微服务相集成,从而形成一个可从两种方法中受益的统一的 GraphQL API。 通过合并模式并解决类型和字段之间的关系,混合图架构提供了灵活性、模块化和可扩展性。

图 14: 混合图

混合图模式为组织提供了利用现有资源的同时逐步采用联合的能力。 它允许联合子图和非联合模式的无缝集成,满足不同的需求并促进互操作性。 这种方法使组织能够构建可扩展并适应不断变化的需求的全面 GraphQL API。 通过结合联合和非联合服务的优势,混合图为构建 GraphQL 部署提供了灵活而强大的解决方案。

GraphQL 部署中混合图的挑战包括管理合并模式的复杂性、解决潜在的性能开销、确保数据一致性和完整性、处理系统演变和版本控制、以及处理分布式架构中的监控和调试的复杂性。 这些挑战需要仔细规划、优化和强大的开发实践来克服并确保混合图部署的顺利运行。 

无服务器路由

此模式涉及将 GraphQL API 部署为一组无服务器函数,例如 AWS Lambda 或 Google Cloud Functions。 这是一种部署 GraphQL API 的经济高效且可扩展的方式,但也会引入额外的延迟并增加架构的复杂性。

无服务器路由面临许多挑战。 一个问题是随着应用的扩展,无缝连接分布式子图。 协调多个团队和部署可能变得复杂,使得有效地管理和扩展子图变得具有挑战性。 确保这些子图之间的数据一致性和同步是另一个障碍。 在分布式无服务器环境中监控和调试可能更加困难,需要适当的日志记录和错误处理机制。 此外,跨多个无服务器功能和子图管理访问控制和授权也带来了挑战。 解决这些挑战对于基于无服务器的 GraphQL 部署的顺利运行和可扩展性至关重要。

边缘部署

在 GraphQL API 的边缘部署模式中,API 使用 CDN 服务放置在更靠近客户端的位置。 这带来了多种好处,包括更低的延迟以实现更快的响应、减少原始服务器上的负载以及防止 DDoS 攻击。

通过在全球的边缘服务器上分布 API 基础设施,它可以更有效地处理流量并在全球范围内提供更好的用户体验。 CDN 的缓存和过滤功能有助于提高可扩展性并确保 API 的可用性,即使在面临大量流量或恶意攻击的情况下。 边缘部署可以利用 CDN 的服务器网络来优化 API 的性能和可靠性。 

结论

GraphQL 技术已经足够成熟,可以被传统企业所接受。 尽管Gartner 的 2022 年 API 成熟度曲线表明,我们距离广泛采用还有几年的时间,但我们现在已经到达一个关键的转折点,必要的工具已经到位。 虽然 GraphQL 还比较新,但它已经发展到可以满足成熟大型企业需求的程度。

GraphAPI 技术的成熟根源于越来越多的企业采用 GraphQL 和其他图形数据库技术。 随着越来越多的公司采用这些技术,支持这些技术所需的工具和资源也越来越多,使得其他企业更容易效仿。 此外, GraphAPI 技术的优势(例如改进数据查询和降低复杂性)正得到越来越广泛的认可,进一步推动了企业公司的采用。

作为一个行业,我们必须认识到 GraphQL 等 GraphAPI 技术的重要性及其克服 REST 限制的潜力。 企业不能忽视投资和理解 GraphQL 的迫切需要,特别是在数据建模、多样性和不透明性方面。 虽然我们很容易迷上 GraphQL 的功能和潜力,但我们也必须承认,在达到过高的期望值之后,可能会陷入幻灭的低谷。 供应商必须优先增强其产品以全面支持 GraphQL,而企业 IT(包括供应商)应该确定哪些数据可以从 GraphQL 的曝光中受益以提高生产力。

客户必须优先了解他们的数据,并认识到普通企业的运营方式与最初引入 GraphQL 的超大规模企业不同。 让我们共同努力,拥抱 GraphQL 作为有效的软件架构模式,推动行业向更高的生产力和创新迈进。

下载报告