PayPal 大规模采用 GraphQL 的探索和实践

如今 GraphQL 在 PayPal 的状态

我们通过构建收银台体验开启了我们的 GraphQL 采用之旅。当我们用GraphQL构建收银台应用程序时,我们看到了采用 GraphQL 的巨大好处,这成为我们的指路明灯。我们构建了更多的应用程序,提供了基础设施支持,发布了一个公共GraphQL API,并在全公司提供了培训和学习材料。我们还建立了一个标准机构,提供了一个 GraphQL 工具 fanny pack,并构建了示例应用程序来帮助团队开始使用 GraphQL。

 

如今,PayPal 的多个生产应用程序都在使用 GraphQL。现在,使用 GraphQL 构建新的 UI 应用程序已经成为默认模式。许多现有应用程序正在迁移到 GraphQL。GraphQL 正被身份(Identity)、支付(Payment)、合规性(Compliance)等常见平台使用,以在所有 PayPal 产品中提供一致的体验。我们的 API 开发人员已经开始使用 GraphQL 来构建 API。Braintree 发布了它的公共GraphQL API

 

在 GraphQL 的帮助下,我们已经能够弥合面向前端应用程序的后端(BFF,backend for frontend)和后端 API 功能之间的差距,因为 GraphQL 可以作为下游 API 的编排层,执行后端 API 的功能,并充当 UI 应用程序的 API 接口。我们正朝着统一的 GraphQL 网关迈进,以支持整个公司。

为什么 PayPal 需要 GraphQL?

当我们选择 GraphQL 时,我们正在寻找一种技术来帮助我们解决以下问题:

  • 过度获取的数据:我们的 REST(代表性状态传输)APIs 发送了客户端需要的部分响应和一些无关数据。由于 REST API 中的服务器决定了数据的形状,我们的 UI 团队花费了大量时间在客户端过滤和解析数据,通常使用诸如 Redux 之类的库来格式化和存储数据。使用 GraphQL,客户端可以请求一组字段,并准确地取回这些字段,从而无需在客户端进行数据格式化和重塑。这大大加快了我们交付 UI 功能的速度,并且使我们的应用程序更轻量。

  • 避免多次请求:通常,为了调用一个需要特定参数的端点,例如/getProfileById/{id},我们必须预先请求调用其它端点,例如getUser{username}来返回id 等参数。这是一个问题,因为我们为了获取一条信息进行了多次往返请求。GraphQL 帮助解决了这个问题,因为它允许我们在一次往返中获取所需的一切。

  • 使客户端保持最新:我们在 REST API 中大量使用 API 版本号。任何时候我们有突破性的改变,我们都会将其发布为一个新的 API 版本。我们面临的问题是,当我们构建一个新版本时,与旧版本集成的客户端如果不与新版本重新集成,就不会收到这些更新。有时,新版本中的文档或参数会发生更改。有了 GraphQL,我们可以发送更新,客户端不再需要担心版本的更新。由于所有更新都发布到了 GraphQL 中的一个端点,因此客户端可以在需要时获取更新的资源,而无需重新集成到新版本。

  • 集成时可以自由使用任何编程语言:原来 Braintree 并没有公共 API。我们支持服务端 SDKs 和客户端 SDKs。挑战在于我们没有所有语言的服务器 SDKs。许多商户出于各种原因不想使用 SDKs。我们决定在服务端上为商户提供更好的 API。这个新的 GraphQL API 提供了强大的控制能力、灵活性、可移植性、可维护性以及在集成时选择任何语言的自由,并提供了我们全球支付平台的可扩展性。您还可以在 API 发布后立即获得更新,而无需更新 SDK。

  • 统一体验:PayPal 中的每个流程都有自己的 NodeJS 应用程序,每个团队都有自己的 ReactJS 实现。我们希望提供一个层来提供统一的前端体验,同时为我们提供一个后端来协调 API。

  • 对于那些没有领域知识的人来说,易于集成:在我们的 Identity 团队中,我们希望在使用我们的服务时提供统一的体验,而不需要 PayPal 系统的领域知识。我们希望控制我们所有系统的身份,并提供一种安全的方式将 PayPal 子系统账户转换为 PayPal 账户。

  • 字段和方法级检测:我们有内部检测工具,可以显示端点花费的时间和使用的参数,但是很难找到使用的字段。如果没有这些信息,我们就无法知道某个字段是否可以安全删除,或者是否仍在使用。使用 GraphQL,我们可以获得字段级的检测,并清楚了解哪个解析器花了多长时间、常见错误以及调用了哪些字段。这个字段级检测有助于智能地弃用不再使用的字段。

  • 与 API 集成时开发人员体验不一致:在 REST API 中,不同团队对同一变量有不同的约定,例如 user、username,使得理解 API 变得更加困难。使用联邦 GraphQL,所有团队共享同一个 schema,因此更容易识别重复项并使变量命名一致。

  • 更容易测试:Apollo Client 等 GraphQL 工具可以更容易地在 React 等 UI 中添加 GraphQL 查询。它有助于保持代码位于同一位置,并有助于调试和分离关注点。它提供了一种干净的开发人员体验,并提高了代码的可测试性。

  • API 探索:我们花了很长时间浏览 API 文档,并弄清楚特定字段使用哪个端点。一旦我们有了一个端点,我们就会复制 URL 并在 Postman 中进行尝试。如果我们遗漏了一个参数,我们将返回文档并再次搜寻这个参数。这使得使用 API 变得比较困难和耗时。有了 GraphQL,我们就有了 Playground 和 GraphiQL 这样的工具,它们不仅可以用来探索 API 和浏览文档,还可以在工具中发出请求。这使得开发过程更加顺利。


图片来源:drmakete lab on Unsplash

为什么我们开始采用 GraphQL?

PayPal 有一套庞大的 REST API,支持应用程序核心功能,并且非常靠近数据库。GraphQL 在我们的应用程序中用作编排层。它位于前端 UI 应用程序和后端 API 层之间,充当面向前端的后端(BFF)。这意味着 UI 应用程序与 GraphQL 端点对话,这些端点确定要调用哪个下游服务。可以直接在 GraphQL 层构建新功能。一些团队选择使用 GraphQL 作为纯编排层,而其它一些团队使用 GraphQL 作为业务逻辑层。

 

收银台团队是第一个率先使用 GraphQL 的团队。Mark Stuart 在《收银台应用程序详解(Checkout app in this blog post in detail)》中分享了我们采用 GraphQL 的过程。当收银台团队展示他们的应用程序时,我们的工程团队真正感受到了编排和开发人员生产力提高的好处。这引发了整个 PayPal 的兴趣,团队开始开发在他们的应用程序中使用 GraphQL 的示例程序。

 

这是新的吸引人的事情。每个人都对这一宣传感到兴奋,但对团队来说最重要的是,编排下游 API 和为客户创建统一体验有多容易。使用 GraphQL,所有下游的复杂性都可以隐藏,客户不必担心找出哪一部分连接到了哪里。它为客户提供了更加连贯的体验。

 

团队开始构建产品,在我们的技术展览中展示,并使其他人也兴奋不已。很快,所有人都感到好奇。一旦我们说服了领导,我们就可以真正起飞了。

我们如何扩大 GraphQL 的采用范围?

当我们开始扩大 GraphQL 的采用范围时,我们意识到每个应用程序都在试图解决自己的 GraphQL 问题。通常,各个团队都在解决相同的问题并重复发明轮子。我们意识到有必要将这些工作统一到一个框架下,因此,我们成立了一个标准机构。我们为工具、前端和中端示例应用程序、异常处理技术和学习资源提供了支持。

 

我们构建了有助于支持 GraphQL 采用的工具:

  • 我们建立了 GraphQL 标准,用于在内部定义 GraphQL API。这些标准定义了命名约定、GraphQL 类型、请求头标准、指令标准和异常处理技术。

  • 所有 GraphQL 操作都需要指定特殊指令,这些指令描述查询、突变和字段的所有授权要求。

  • 通用库包括用于日志记录的插件、用于数据分类的指令、Apollo 和 playground 的插件、CLI、异常类和 Apollo graph 变体。

  • 前端和后端的模板示例程序。

  • 学习资源,用于帮助团队入门 GraphQL。

  • Slack 频道,帮助回答常见问题并创建内部 GraphQL 社区。

 

拥有一个标准机构和工具非常棒,可以帮助团队更快地建立他们的图。然而,我们注意到有些问题仍然存在。我们注意到某个图偏离了正确的操作方式,例如身份验证。我们在单个图中失去了对认证流程的控制。我们还认识到,拥有多个图会使 schema 共享更加困难。我们希望提供一个统一的入口点,共同管理 schema,以全局方式对数据建模,并提供一种重用类型的方式。这就是促使我们使用Apollo Federation构建了一个单图网关的原因。

采用 GraphQL 有哪些优势?

我们能够协调周边服务,并将一个 PayPal 子系统的账号转变为一个 PayPal 账户,这很让我们自豪。我们最初发布了我们的 Braintree API,我们能够很快完成它。交付速度更快,GraphQL 能够报告使用了 schema 的哪一部分。我们已经看到的 GraphQL 的主要优势有:

  • 开发人员生产力GraphiQLPlayground等工具非常适合使用 API 的同时浏览文档,而无需借助其它任何工具(如 Postman)。

  • 可以访问整个 schema:由于所有操作(查询和更改)都是在同一个端点,因此访问 API 支持的所有操作变得更加容易。

  • 团队协作:与 GraphQL API 并行构建 UI 有助于团队协作。由于 GraphQL schema 需要预先构建,后端工程师和前端工程师一起工作,从而减少了信息隔阂。

  • 范式转换:由于 GraphQL 要求采用设计优先的方法,我们在启用业务用例时考虑 GraphQL,并在考虑客户的情况下构建 API。

  • 更快的交付速度:我们能够更快地交付功能。我们能够摆脱许多弯道,它们使得提供功能更新和保持功能对等变得更难。以前,我们必须用我们的商户使用的每种语言交付一个 SDK。现在,我们可以只提供一个 GraphQL 端点,商户无论使用哪种语言都可以与之集成。

  • 简化统一:内部客户端和周边客户端不再需要担心内部系统的复杂性,也不需要确定调用哪个 API。GraphQL 层将复杂性隐藏在幕后。

  • 分析:对特定字段的单个请求花费的时间进行检测。

  • 曝光和招聘:社区中的许多人对 GraphQL 感到兴奋,它帮助我们吸引人才加入 PayPal。我们的团队成员很高兴能在社区中分享他们的学习成果,并一直在会议上发言、撰写博客文章和制作教学资源。Vishakha Singh就使用GraphQL在PayPal构建更快的收银台体验进行了演讲。Rohit Basu 谈到了用Kotlin和GraphQL工作。我们在JS @ PayPal公开会上多次讨论了我们是如何在各种应用程序中使用 GraphQL 的。

我们面临哪些挑战?


图片来源:Possessed Photography on Unsplash

 

我们仍在创建一种标准方法来应对 GraphQL 技术中的挑战,如异常处理、身份认证、文件处理和批处理。

 

各个团队都在独立地构建他们自己的图,这会导致重复工作、不同的异常处理和呈现方式,以及与处理身份认证标准方式的偏差。

 

我们仍在整合内部工具。由于这些工具很多依赖于 API 响应的状态码——200、400、500 等等,因此我们很难将 GraphQL 响应(都是 200)映射到这些工具。

 

PayPal 的 GraphQL 增长非常快。许多团队构建了他们自己的方法来处理异常,解决 GraphQL 问题,并对内部日志系统进行检测。在它发展之后,我们通过添加内部插件和中间件来提供支持,以规范化错误处理、检测和减少内部网络聊天,但我们希望能够更快地构建支持。

 

我们对单图方案的采用速度很慢。各个团队必须改变他们目前制作应用程序的许多行为,才能采用单图,增加了交付过程和时间。挑战在于告诉人们,现在我们有规则可以添加到图中,但要让他们有动力使用单图。Joey Nenni在JS @ PayPal上发表演讲,谈到了我们实现单图的方案,以及克服这一挑战的潜在解决方案。

我们如何说服我们的工程和领导团队?

我们的前端开发人员立即看到了使用 GraphQL 的好处。说服在 UI 团队中工作的后端开发人员也很容易。他们理解使用 GraphQL 进行编排的力量。对于核心平台 API 团队,我们还没有完全说服他们。当我们介绍 GraphQL 概念时,有时我们被告知 REST 也可以这样做。是的,它可以,我们也可以使用 REST 复制 GraphQL 所做的事情,但最后,我们只是在重新创建 GraphQL。我们还没有得到所有前端或后端开发人员的完全认证,但是我们的 REST API 和 GraphQL API 可以共存。我们学会了不操之过急,一点点来。


图片来源:Christoffer Engström on Unsplash

 

为了说服我们的领导,我们知道仅仅关注 GraphQL API 的性能是不够的。编排的 GraphQL API 的性能取决于它所使用的 API。GraphQL API 的速度仅与最慢的下游 API 的速度相同。相反,我们将重点放在开发人员的生产力和交付产品的时间上。我们演示了使用 GraphQL 可以帮助更快地构建产品,提升团队协作,并使文档更容易浏览。当我们向我们的团队介绍 GraphiQL 和 Playground 工具时,他们立刻看到了使用 GraphQL 端点和 playground 工具来在浏览文档时发出请求的好处。

 

我们演示了 GraphQL 如何帮助提高内部和外部开发人员的生产力,GraphQL 如何帮助减少交付功能的时间,以及我们如何能够向客户端隐藏复杂性。使用 GraphQL,我们不必为每个平台编写多个 SDK。我们构建一次 API 就可以了。没有 GraphQL,我们不知道商户正在使用哪些字段以及调用了哪些端点。我们在 KPI 上没有指标,例如首次集成到生产中。通过 GraphQL,我们能够展示我们的学习、工具和字段级别的监测情况。

你如何开始在自己的公司采用 GraphQL?

  1. 当你第一次推测 GraphQL 是否是正确的技术时,构建一个示例应用程序来演示 GraphQL 如何适合你的企业架构是很有帮助的。

  2. 带上团队——演示你的应用程序并展示使用 GraphQL 的好处,你采用 GraphQL 的经历,你所看到的好处,以及你在帮助公司其他人方面所面临的困难。

  3. 为成功建立机构——成立一个工作组,帮助建立标准。为 GraphQL 建立学习资源、提供指导、构建工具和支持。

  4. 让团队参与进来——从生产力的角度展示使用 GraphQL 的优势。每个人都希望更快地发布产品,并使其更容易与 API 集成。GraphQL 正好提供了这一点。向你的团队成员和领导演示使用 GraphQL 构建新功能是多么容易,向现有客户发送更新是多么容易,而不必发布新版本,同时仍然向后兼容。

特别鸣谢


图片来源:Wilhelm Gunkel on Unsplash

 

这篇文档是我们宝贵的团队成员的贡献促成的。感谢Mark StuartJoey NenniWalmik DeshpandeMiriam Goldberg,感谢他们愿意接受采访并分享他们的经历。非常感谢 Mark Stuart 在 PayPal 中领导 GraphQL 的采用,激励我分享我的 GraphQL 经验,并激励我们的开发者社区。

作者介绍:

Shruti Kapoor 是 PayPal 的软件工程师、freecodecamp 和 codeburst 的作家,写一些 JavaScript 相关的内容。Twitter:shrutikapoor08

原文链接:

GraphQL at PayPal: An Adoption Story

本文文字及图片出自 InfoQ

你也许感兴趣的:

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注