PayPal采用GraphQL的故事


我们通过建立结账体验开始了我们的 GraphQL 采用之旅。当我们使用 GraphQL 构建的结账应用程序成为我们的指路明灯时,我们看到了采用 GraphQL 的巨大好处。我们构建了更多应用程序,提供了基础设施支持,推出了公共 GraphQL API,并在整个公司提供了培训和学习材料。我们还建立了一个标准机构,提供了一个 GraphQL 工具腰包,并构建了示例应用程序来帮助团队入门。
如今,PayPal 上的多个生产应用程序都在使用 GraphQL。现在是使用 GraphQL 构建新 UI 应用程序的默认模式。许多现有的应用程序正在迁移到 GraphQL。GraphQL 正被身份、支付和合规等通用平台使用,以在所有 PayPal 产品中提供一致的体验。我们的 API 开发人员已经开始使用 GraphQL 来构建 API。Braintree 发布了其公共 GraphQL API
在 GraphQL 的帮助下,我们已经能够弥合前端 (BFF) 应用程序后端和后端 API 功能之间的差距,因为 GraphQL 可以作为下游 API 的编排层,执行后端 API 的功能,并作为UI 应用程序的 API 接口。我们正在朝着统一的 GraphQL 网关迈进,以通过公司支持一个图。
 
为什么 PayPal 需要 GraphQL?
当我们选择 GraphQL 时,我们正在寻找一种技术来帮助我们解决以下问题:

  • 过度获取数据:我们的 REST(代表性状态传输)API 发送了客户端需要的部分响应和一些无关数据。由于 REST API 中的服务器决定了数据的形状,因此我们的 UI 团队花费了大量时间在客户端过滤和解析数据,通常使用 Redux 等库来格式化和存储数据。使用 GraphQL,客户端可以请求一组字段,并准确地取回这些字段,从而无需在客户端进行数据格式化和重塑。这大大增加了发布 UI 功能和使我们的应用程序轻量级所需的时间。
  • 避免多次往返:通常,为了调用一个需要特定参数的端点,例如/getProfileById/{id},我们必须调用额外的端点作为先决条件,例如getUser{username}返回参数,例如id。这是一个问题,因为我们进行了多次往返以获取一条信息。GraphQL 帮助解决了这个问题,因为它允许我们在一次往返中获取我们需要的一切。
  • 使客户端保持最新状态:我们在 REST API 中大量使用 API 版本。每当我们有重大更改时,我们都会将其发布为新的 API 版本。我们面临的问题是,当我们创建新版本时,与旧版本集成的客户端在不与新版本重新集成的情况下将不会收到这些更新。有时文档或参数会在新版本中发生变化。使用 GraphQL,我们能够发送更新,并且客户不再需要担心与版本保持同步。由于所有更新都发布到 GraphQL 中的一个端点,因此客户端可以在需要时获取更新的资源,而无需重新集成新版本。
  • 集成时可以自由使用任何编程语言:从历史上看,Braintree 没有公共 API。我们支持服务器 SDK 和客户端 SDK。挑战在于我们没有所有语言的服务器 SDK。许多商家出于某种原因不想使用 SDK。我们决定需要为服务器上的商家提供更好的 API。这个新的 GraphQL API提供了强大的控制、灵活性、可移植性、可维护性和在集成时选择任何语言的自由,并为我们的全球支付平台提供了可扩展性。您还可以在 API 发布后立即从这些更新中获得更新,而无需更新 SDK。
  • 统一体验: PayPal 中的每个流程都有自己的 NodeJS 应用程序,每个团队都有自己的 ReactJS 实现。我们希望提供一个层来提供统一的前端体验,同时为我们提供一个后端来编排 API。
  • 对于没有先验领域知识的人来说易于集成:在我们的身份团队中,我们希望在使用我们的服务时提供统一的体验,而无需了解 PayPal 系统的领域知识。我们希望控制我们所有邻接方的身份,并提供一种安全的方式将 PayPal 附属账户转换为 PayPal 账户。
  • 字段和方法级检测:我们有内部检测工具,可以显示端点花费的时间和使用了哪些参数的指标,但很难找到正在使用哪些字段。如果没有这些信息,我们就无法知道某个字段是否可以安全删除或是否仍在使用中。使用 GraphQL,我们可以获得字段级别的检测,并清楚地了解哪个解析器花费了多长时间、常见错误以及调用了哪些字段。此字段级检测有助于智能地弃用不再使用的字段。
  • 与 API 集成时不一致的开发人员体验:在 REST API 中,不同的团队对相同的变量(例如用户)会有不同的约定,username这使得 API 更难理解。使用联合 GraphQL 和一个图,所有团队共享相同的模式,因此识别重复项和一致命名变量变得更加容易。
  • 更轻松的测试: Apollo Client 等 GraphQL 工具可以更轻松地在 React 等 UI 中添加 GraphQL 查询。它有助于将代码保持在同一位置,并有助于调试和分离关注点。它提供了干净的开发人员体验并提高了代码的可测试性。
  • API 探索:我们花了大量时间浏览 API 文档并确定用于特定领域的端点。一旦我们有了一个端点,我们就会复制这些 url 并在 Postman 中试用它们。如果我们错过了一个参数,我们将返回文档并再次搜索该参数。它使使用 API 变得更加困难和耗时。使用 GraphQL,我们获得了 Playground 和 GraphiQL 等工具,它们不仅可以用于探索 API 和浏览文档,还可以在工具中直接发出请求。这使得开发过程更加顺畅

 
如何开始采用 GraphQL 的?
PayPal 拥有一套广泛的 REST API,可为应用程序的核心功能提供支持,并且非常靠近数据库。GraphQL 在我们的应用程序中用作编排层。它位于前端 UI 应用程序和充当前端后端 (BFF) 的后端 API 层之间。这意味着 UI 应用程序与 GraphQL 端点通信,并且端点确定要调用哪个下游服务。新功能可以直接在 GraphQL 层中构建。一些团队选择使用 GraphQL 作为纯编排层,而其他团队则使用 GraphQL 层作为业务逻辑层。
Checkout 团队是第一个采用 GraphQL 的先驱。Mark Stuart在这篇博文中详细分享了我们在Checkout 应用程序中采用 GraphQL 的过程当 Checkout 团队展示他们的应用程序时,我们的工程团队真正感受到了编排和提高开发人员生产力的好处。这引起了整个 PayPal 的兴趣,团队开始开发演示应用程序以在他们的应用程序中使用 GraphQL。
这是新的闪亮的东西。每个人都对炒作感到兴奋,但对团队来说最突出的是编排下游 API 并为客户创建统一体验是多么容易。使用 GraphQL,可以隐藏所有下游的复杂性,客户端不必担心找出哪个部分连接到哪里。它为客户提供了更连贯的体验。
团队开始构建产品,在我们的技术展示中展示它们,也让其他人感到兴奋。很快,大家都好奇了。一旦我们获得了领导权,我们就真的能够起飞了。
 
我们如何扩大 GraphQL 的采用?
当我们开始扩大 GraphQL 的采用范围时,我们意识到每个应用程序都在努力解决自己的 GraphQL 问题。通常,团队正在解决相同的问题并重新发明轮子。我们意识到有必要将这些努力统一在一个保护伞下,因此,我们建立了一个标准机构。我们为工具、前端和中间层示例应用程序、错误处理技术和学习资源提供支持。
我们构建了工具来帮助支持 GraphQL 的采用:
  • 我们为内部定义 GraphQL API 建立了 GraphQL 标准。这些标准定义了命名约定、GraphQL 类型、标头标准、指令标准和错误处理技术。
  • 所有 GraphQL 操作都需要指定特殊指令来描述查询、突变和字段的所有授权要求。
  • 公共库包括日志插件、数据分类指令、Apollo 和 Playground 中间件、CLI、错误类和 Apollo 图变体。
  • 前端和后端的模板示例应用程序。
  • 学习资源以帮助团队加入 GraphQL。
  • 帮助回答常见问题并创建内部 GraphQL 社区的 Slack 频道。

拥有标准机构和工具很棒,可以帮助团队更快地设置图表。但是,我们注意到一些问题仍然存在。我们注意到个别图表偏离了正确的做事方式,例如身份验证。我们在个别图表中失去了对 auth rails 的一点控制。我们还意识到拥有多个图会使模式共享更加困难。我们希望提供一个集中的入口点,一起管理模式,以全局方式对数据建模,并提供一种重用类型的方法。这就是促使我们使用Apollo Federation构建单图网关的原因。
 
采用 GraphQL 有哪些优势?
我们能够协调相邻关系并将 PayPal 子公司的身份转换为 PayPal 帐户,这一事实令人自豪。我们最初推出了我们的 Braintree API,我们能够非常快速地完成它。交付时间更快,并且 GraphQL 能够报告哪个模式去了哪里。我们已经看到 GraphQL 的主要优点是:
  • 开发人员生产力:GraphiQLPlayground等工具非常适合使用 API 并同时浏览文档,而无需查看任何其他工具,例如 Postman。
  • 访问整个模式:由于所有操作(查询和更改)都在同一个端点,因此可以更轻松地访问 API 支持的所有操作。
  • 团队协作:与 GraphQL API 并行构建 UI 有助于增强团队协作。由于需要预先构建 GraphQL 模式,因此后端和前端工程师协同工作,从而减少孤岛。
  • 范式转变:由于 GraphQL 要求采用设计优先的方法,因此我们在支持业务用例的背景下考虑了 GraphQL,并在构建 API 时考虑到了客户。
  • 更快的运输:我们能够更快地交付功能。我们能够摆脱许多管道,这些管道使提供功能更新和保持功能奇偶校验变得更加困难。以前,我们必须以商家使用的每种语言发布 SDK。现在,我们可以提供一个单一的 GraphQL 端点,商家无论使用哪种语言都可以将其集成。
  • 简化统一:内部客户端和邻接方不再需要担心内部系统的复杂性并确定要调用哪个 API。GraphQL 层隐藏了幕后的复杂性。
  • 分析:对特定字段的单个请求花费多长时间的检测。
  • 曝光和招聘:社区中的许多人都对 GraphQL 感到兴奋,它帮助我们为 PayPal 吸引人才。我们的队友很高兴能在社区中分享他们的学习成果,并一直在会​​议上发言、撰写博客文章和制作教学资源。

 
面临哪些挑战?
我们仍在努力创建一种标准化的方法来应对 GraphQL 技术中的挑战,例如错误处理、身份验证、文件处理和批处理。
团队独立构建自己的图表,这会导致重复工作、不同的处理和显示错误的方式,以及与处理身份验证的标准方式的偏差。
我们仍在努力整合内部工具。由于很多这些工具依赖于 API 响应的状态代码——200s、400s、500s,我们很难将 GraphQL 响应(所有 200s)映射到这些工具。
PayPal 的 GraphQL 增长非常快。许多团队建立了自己的处理错误、解决 GraphQL 问题和检测内部日志系统的方式。在它发展壮大后,我们通过添加内部插件和中间件来提供支持,以规范错误处理、检测和减少内部网络闲聊,但我们希望我们能尽快建立支持。
 
如何说服我们的工程和领导团队?
我们的前端开发人员立即看到了使用 GraphQL 的好处。说服在 UI 团队工作的后端开发人员也很容易。他们了解使用 GraphQL 进行编排的力量。对于核心平台 API 团队,我们还没有完全说服他们。当我们介绍 GraphQL 概念时,有时我们被告知 REST 也可以做到这一点。是的,我们也可以用 REST 复制 GraphQL 所做的事情,但最终,我们只是在重新创建 GraphQL。我们还没有得到整个堆栈开发人员的完全支持,但我们的 REST 和 GraphQL API 可以共存。
为了说服我们的领导层,我们知道仅仅关注 GraphQL API 的性能是不够的。编排的 GraphQL API 的性能取决于它使用的 API。GraphQL API 的速度与其最慢的下游 API 一样快。相反,我们专注于开发人员的生产力和交付产品的时间。我们证明了使用 GraphQL 可以帮助更快地构建产品、改善团队协作并更容易地浏览文档。当我们向我们的团队介绍 GraphiQL 和 Playground 工具时,他们立即看到了使用 GraphQL 端点和 Playground 工具在浏览文档时触发请求的好处。
我们展示了 GraphQL 如何帮助提高内部和外部开发人员的生产力,GraphQL 如何帮助减少交付功能的时间,以及我们如何能够向客户隐藏复杂性。使用 GraphQL,我们不必为每个平台开发多个 SDK。我们构建了一次 API,就大功告成了。如果没有 GraphQL,我们不知道商家正在使用哪些字段以及调用了哪些端点。我们没有关于 KPI 的工具,例如首次集成到生产中。使用 GraphQL,我们能够展示我们的学习、仪器和现场级洞察力。
 
您如何在自己的公司开始采用?
  1. 当第一次推测 GraphQL 是否是正确的技术时,构建一个演示应用程序会很有帮助,该应用程序可以演示 GraphQL 如何适合您的企业架构。
  2. 带上团队 — 演示您的应用程序并展示使用 GraphQL 的好处、您采用 GraphQL 的经验、您所看到的优势以及您在帮助公司其他人时所面临的困难。
  3. 为成功建立企业——成立一个工作组,帮助建立标准。为 GraphQL 设置学习资源、提供指导以及构建工具和支持。
  4. 让团队加入——从生产力的角度展示使用 GraphQL 的优势。每个人都希望更快地交付产品并更轻松地与 API 集成。GraphQL 正好提供了这一点。向您的团队成员和领导展示使用 GraphQL 构建新功能是多么容易,以及在无需发布新版本的情况下向现有客户端发送更新是多么容易,同时仍然向后兼容。