Netflix:我们为什么要将GraphQL引入前端架构?

作者|Artem Shtatnov译者|无明

在这篇文章中,我们将分享 Netflix 在这些应用程序的前端架构中引入 GraphQL 所积累的经验。

在内部,我们把用于管理广告创建和组装的主要应用程序叫作 Monet。它用于增强广告的创建以及自动管理外部广告平台上的营销广告活动。Monet 有助于推动流量增量转换,增强用户与产品的互动,并向全世界的用户展示我们的内容和 Netflix 品牌。

首先,它有助于扩展和自动化广告创建以及管理数百万个广告素材组合。其次,我们利用各种信号和汇总数据(例如 Netflix 上的内容流行度)来实现高度相关的广告。我们的总体目标是使所有外部发布渠道上的广告都能够让用户产生共鸣,并且不断尝试提高有效性。

背 景

在刚开始时,Monet 的 React UI 层需要访问由 Tomcat 服务器提供的传统 REST API。随着时间的推移,随着应用程序的发展,我们的用例变得越来越复杂,即使是一个简单页面也需要从各种来源提取数据。

为了更有效地将这些数据加载到客户端,我们首先尝试对后端的数据进行非规范化。但这种非规范化变得难以维护,因为并非所有页面都需要所有数据。我们很快遇到了网络带宽瓶颈。浏览器需要获取比以往更多的非规范化数据。

为了减少发送给客户端的字段数量,一种方法是为每个页面构建自定义端点,但这很明显不是一个好的解决方案。我们没有去构建自定义端点,而是选择 GraphQL 作为应用程序的中间层。

我们还将 Falcor 作为一种可能的解决方案,因为它在 Netflix 的很多核心用例中已经取得了很好的成果,并且得到了大量的采用,但因为 GraphQL 强大的生态系统和第三方工具,我们认为 GraphQL 对我们的用例来说会是更好的选择。此外,随着我们的数据结构越来越以图形为导向,GraphQL 最终会变得更加合适我们的用例。引入 GraphQL 不仅解决了网络带宽瓶颈问题,而且还提供了很多其他优势,让我们能够更快地添加功能。

我们已经在 NodeJS 上运行 GraphQL 大约 6 个月,并且它已经被证明可以显著提高我们的开发速度和整体页面的加载性能。以下是从我们开始使用它以来给我们带来的一些好处。

GraphQL 优点 重新分配负载和优化有效载荷

通常,某些机器比其他机器更适合用来完成某些任务。当我们引入 GraphQL 中间层后,GraphQL 服务器仍然需要调用与客户端相同的服务和 REST API。现在的区别在于,大多数数据是在同一数据中心内的服务器之间流动。这些服务器到服务器之间的调用具有非常低的延迟,而且带宽非常高,与来自浏览器的直接网络调用相比,性能提升了 8 倍。

从 GraphQL 服务器到客户端浏览器的最后一英里数据传输现在减少到了单个网络调用。由于 GraphQL 允许客户端选择它需要的数据,所以我们只需要获取更小的有效载荷。

在我们的应用程序中,之前需要获取 10MB 数据的页面现在只需要获取 200KB。页面加载速度变得更快,特别是在数据受限的移动网络上,我们的应用程序使用的内存也更少了。这些变更是以提高服务器利用率为代价的,服务器需要进行数据的获取和聚合,不过虽然牺牲了这额外的几毫秒服务器时间,却换来了较小的客户端有效载荷。

可重用的抽象

软件开发人员通常希望使用可重用的抽象而不是单一用途的方法。在使用 GraphQL 时,我们定义了数据以及与数据之间的关系。当消费者应用程序从多个源获取数据时,不需要操心与数据连接操作相关联的复杂业务逻辑。

例如,我们只在 GraphQL 中定义一次实体:catalog、creative 和 comment。我们现在可以基于这些定义构建多个页面视图。客户端应用程序(catalogView)的一个页面想要获得 catalog 中所有 creative 的所有 comment,而另一个客户端页面(creativeView)想要知道 creative 和相关 comment 所属的 catalog。

链接类型系统

很多人专注于单一服务中的类型系统,但很少关注跨服务。在 GraphQL 服务中定义了实体之后,我们就会使用自动生成工具为客户端应用程序生成 TypeScript 类型。React 组件的 prop 接收类型以匹配组件查询。由于这些类型和查询也需要通过服务器 schema 的验证,因此服务器的任何重大更改都将被使用数据的客户端捕获到。

使用 GraphQL 将多个服务链接在一起,并将这些检查过程集成到构建过程中,可以在部署错误代码之前捕获更多问题。理想情况下,我们可以实现从数据库层一直到客户端浏览器的类型安全性。

DI/DX——简化开发

创建客户端应用程序时人们比较关心的是 UI/UX,但开发者接口和开发者体验对于构建可维护应用程序来说同样重要。在使用 GraphQL 之前,编写一个新的 React 容器组件需要维护复杂的逻辑。

开发人员需要考虑数据之间的相关性、如何缓存数据、是否进行并行调用还是串行调用以及在 Redux 的什么地方保存数据。在使用 GraphQL 查询包装器后,每个 React 组件只需要描述它需要的数据,包装器会处理所有其他问题。这样样板代码更少了,数据和 UI 之间的关注点也更清晰了。这种声明性数据提取模型让 React 组件变得更容易理解。

其他好处

我们也注意到了其他的一些较小的好处。首先,如果 GraphQL 查询的某些解析器失败,成功的解析器仍然会将数据返回到客户端,并尽可能多地渲染页面。其次,后端数据模型得到大大的简化,因为我们不需要关心客户端的模型,并且在大多数情况下可以只提供原始实体的 CRUD 接口。最后,测试组件也变得更容易,因为 GraphQL 查询被自动转换为测试存根,我们可以独立于 React 组件测试解析器。

成长的烦恼

基于我们为网络请求和转换数据构建的大多数基础设施,可以轻松地将 React 应用程序转到 NodeJS 服务器上,无需更改任何代码。我们删除的代码比我们添加的还要多。但是,在迁移过程中,我们难免要克服一些障碍。

自私的解析器

GraphQL 中的解析器作为独立单元运行,不需要关心其他解析器,因此我们发现它们对相同或类似的数据进行了很多重复的网络请求。我们通过为数据提供者提供一个简单的缓存层来解决这种重复问题,这个缓存层将网络响应保存在内存中,直到所有解析器处理完毕。缓存层还允许我们将对单个服务的多个请求聚合成一次性请求。解析器现在可以请求它们需要的任何数据,无需操心如何进行优化数据的获取过程。

我们编织的糟糕的 Web

抽象是提高开发人员效率的好办法...... 直到出现问题。毫无疑问,我们的代码中存在 bug,我们不希望中间层将 bug 的根源隐藏掉。GraphQL 会自动编排对其他服务的网络调用,从而隐藏用户的复杂性。服务器日志可以作为一种调试方法,但仍然不能使用浏览器实现这一步的调试。为了使调试更容易,我们将日志直接添加到 GraphQL 响应有效载荷中,显示了服务器正在处理的所有网络请求。在启用调试标志后,你将在浏览器中获得与使用浏览器进行网络调用时相同的数据。

被破坏的类型

GraphQL 破坏了 OOP 的范式,当我们获取部分对象时,这些数据不能用于需要完整对象的方法和组件。当然,你可以手动转换这些对象,但是你会失去类型系统的很多好处。所幸的是,TypeScript 支持动态类型,因此我们可以调整方法,让它们只需要获得真正需要的对象属性即可。定义这些更精确的类型需要更多的工作量,但总体上能够提供更大的类型安全性。

接下来

我们仍然处于探索 GraphQL 的早期阶段,到目前为止,这是一次积极的体验,我们很高兴能够采用它。我们的关键目标之一是在系统变得日益复杂的同时帮助我们提高开发效率。

我们希望在图数据模型上进行投入,以便随着更多边和节点的增加,我们的团队将变得更加高效,而不是陷入复杂数据结构的泥潭中。在过去的几个月,我们已经发现现有的图模型已经变得足够强大,不需要修改图就可以构建出一些功能,GraphQL 确实使我们更有成效。

随着 GraphQL 继续发展和不断成熟,我们期待从社区学习到更多东西。在实现层面,我们期待使用一些很酷的概念,如模式拼接,这让与其他服务的集成变得更加简单,并节省大量的开发时间。最重要的是,让公司的更多团队看到 GraphQL 的潜力并开始采用它是一件非常令人兴奋的事情。

英文原文

https://medium.com/netflix-techblog/our-learnings-from-adopting-graphql-f099de39ae5f

原文地址:https://www.cnblogs.com/Yanss/p/10140966.html

时间: 2024-10-14 08:32:26

Netflix:我们为什么要将GraphQL引入前端架构?的相关文章

用“MEAN”技术栈开发web应用(一)AngularJs前端架构

前言 不知何时突然冒出“MEAN技术栈”这个新词,听起来很牛逼的样子,其实就是我们已经熟悉了的近两年在前端比较流行的技术,mongodb.express.angularjs.nodejs,由于这几项技术涵盖了从前端到后端再到数据库,可以用他们完整的开发一个web应用了,所以成了一个非常牛逼的组合,颇有当年LAMP的气势.前端要从切图仔迈向全栈的路上,这几门技术必须得有所涉猎.本系列文章利用自己虚构的一个小项目为例,对“使用MEAN技术栈开发web应用”做一个入门级的介绍. AngularJs的争

前端架构浅谈

前端架构浅谈 0.前注 鉴于作者本人的能力有限(非常有限),并且依然在学习中,因此本文的高度和深度必然有所欠缺. 欢迎(并且非常欢迎)大家来批评指正,如果能详细的说明问题在哪里,如何解决和改正,那么就太感谢了!!! 我最喜欢听有理有据的批评了!! 本人QQ:20004604,邮箱:[email protected],期待你的交流. 1.为什么要有一个好的架构 首先明确一点,架构是为需求服务的. 前端架构存在的目的,就我个人理解来说,有以下几点: 1.提高代码的可读性. 一个好的架构,代码的可读性

24Web前端架构

近来都是接触前端,所以学多点这方面的东西,虽说有实战到项目里面去了,但可能还没走到所谓正确的道路上去.欢迎交流. 转载请说明来着:http://blog.csdn.net/wowkk --------------------------------------------------------------------------------------------- 如果Web前端做多了一点,那就会意识到,无论项目大小,都得考虑到一个"架构"的问题. 因为只要是项目,就会涉及到&qu

关于互联网应用前端架构的一些思考

一.互联网应用的分类. 讨论前端架构之前,首先要弄清楚互联网应用的类型,明确了自己的产品所属的类型才能打造属于自己的架构.对互联网产品进行分类,网上有很多不同的观点.我觉得分类是多维度的,但是按照交互以及功能的复杂程度来分类是比较客观的.因此,我比较认同淘宝玉伯在关于前后端开发模式中对应用的分类,以下引用玉伯的观点: 前端涉及的产品形态在业界可分为两大类:Web Pages 和 Web Apps . Web Pages 是浏览类的,用户主要是来看的:以内容展现为主,辅有少量交互.前端提供基础类库

基于AngularJS的企业软件前端架构[转载]

这篇是我参加QCon北京2014的演讲内容: 提纲: 企业应用在软件行业中占有很大的比重,而这类软件多数现在也都采用B/S的模式开发,在这个日新月异的时代,它们的前端开发技术找到了什么改进点呢? B/S企业软件前端开发模式大体上与桌面软件类似,都是偏重量级的,在前端可能会有较多的业务逻辑,这些业务逻辑如何被合理模块化,与界面分离,以便测试,成为这个领域的一个重要挑战.另一方面,由于企业应用的界面相对规整,偏重的是数据存取,没有太多花哨的东西,所以常见的界面控件也是可枚举的,如何让开发界面的工作能

使用模块化思维和模板引擎搭建前端架构(require+underscore)

require.js 介绍: 是一个非常小巧的JavaScript模块载入框架,是AMD规范最好的实现者之一.最新版本的RequireJS压缩后只有14K,堪称非常轻量. 官网:http://www.requirejs.cn/    (PS:如果没接触过,刚开始看都是一头蒙蔽的,建议看下菜鸟教程) 新手教程:http://www.runoob.com/w3cnote/requirejs-tutorial-1.html 优点:可完成团队协作.模块复用.单元测试等等一系列复杂的需求 undersco

WEB前端开发电商网站前端架构

课程介绍通过一个垂直电子商务网站,介绍前端架构搭建和实现的步骤和方法,以及在这个过程中我们需要做什么才能帮助项目最终从设计走向实现.课程提纲第1章 前端架构知识准备认识前端架构,了解前端架构技术.产品设计和发布.数据分析和优化的基础第2章 前端架构设计了解前端架构的组织方式.页面层次的架构组织.架构设计和组件化方案等.第3章 前端架构实施了解架构的实施.优化思路,如何实施自动化.通过蛋糕电商网站讲解,分析案例.如何图解设计和交互图.如何从目录入手搭建基本架构.如何从页面层次进行架构搭建和最后项目

web富客户端应用下,前端架构问题。

前言: 以前的工作大部分都是,前端做页面 稍微写几个js效果就算是 有复杂的效果 也没有涉及到 需要去调用后端数据的层面.总体来说,以前的页面逻辑会相对简单后端会做更多的事. 而现在,这些任务都抛给前端来做了..  前端的业务逻辑变得很复杂 有的时候甚至 比后端的更复杂.(当然这个也跟写接口的人水平有关...) 在这样的背景下面,如果还是以前那套 页面里面写js 或者哪里有效果写哪里的话.无论是实现,还是后面的维护都是一个很大的问题.. 所以,我觉得富客户端web应用,很有必要组建一个自己的前端

没有最好,选择最适合自己的前端架构

前端框架不断推新,众多IT企业都面临着"如何选择框架","是否需要再造轮子"的抉择.去哪儿网前端架构师司徒正美分析了各主流行框架优劣点.适用场景,并针对不同规模的公司.项目给出了相应的前端技术选择方案. 最近几年,前端技术迅猛发展,差不多每年都会冒出一款主流的框架. 每次新开业务线或启动新项目时,首先第一件事就是纠结:使用什么框架,重造什么轮子?我很高兴应CSDN的邀请谈我的看法. RequireJS,前端技术发展分水岭 在五六年前,移动端还没有兴起,我们没有什么选