- 原文地址:Our learnings from adopting GraphQL: A Marketing Tech Campaign
- 原文做者:Netflix Technology Blog
- 译文出自:掘金翻译计划
- 本文永久连接:github.com/xitu/gold-m…
- 译者:Sam
- 校对者:lianghx-319
在以前的博客文章中,咱们对营销技术团队的一些应用程序提供了高级概述,咱们这么作是为了推进全球广告业务实现 体量化和智能化,使得广告能够经过像纽约时报,Youtube 等网站覆盖成千上万的用户。在这篇博文中,咱们将分享关于咱们更新前端架构的过程和在营销技术团队中引入 GraphQL 的经验。前端
咱们用于管理建立和装配广告到外部部署平台的核心应用程序在咱们内部被称为 Monet。它用于加强广告的建立和自动化管理在外部广告平台的营销活动。Monet 帮助推进增量转化,一般是和咱们的产品进行交互,为全球各地的用户展现关于咱们内容和 Netflix 品牌的精彩故事。为此,首先,它帮助扩展和自动化广告产品,而且管理数百万广告素材队列。其次,咱们借用多种信号和汇总数据(例如了解在 Netflix 上的内容流行度)以实现高度相关的广告。咱们整体目标是确保咱们全部在外部发布频道的广告可以很好的引发用户的共鸣,而且咱们不断尝试提升咱们这么作的有效性。android
Monet 和高级营销技术流程ios
在咱们开始的时候,Monet 的 React UI 层访问的是由 Apache Tomcat 服务提供的传统 REST API。随着时间的推移,咱们应用程序的发展,咱们的用例变得更加复杂。简单的页面须要从各类来源中获取数据。为了更加高效的在客户应用程序中加载这些数据,咱们首先尝试在后端对数据进行非规范化处理。因为不是全部页面都须要全部这些数据,管理这些非规范化(的数据)变得难以维持。咱们很快就遇到了网络带宽瓶颈。浏览器须要获取比以往更多的非规范化数据。git
为了减小发送给客户端的字段数量,一种方法是为每一个页面建立自定义端点;这是一个明显不切实际的想法。咱们选择使用 GraphQL 做为咱们应用的中间层,而不是建立这些自定义端点。咱们也考虑过把 Falcor 做为一个可能的解决方案,毕竟它在 Netflix 的不少用例中展示出很好的成果而且大量的使用,可是 GraphQL 健壮的生态体系和强大的第三方工具库使得 GraphQL 成为咱们用例更好的选择。此外,随着咱们数据结构愈来愈面向图形化,使用 GraphQL 最终适配会很是天然。添加 GraphQL 不只解决了网络带宽瓶颈问题,并且还提供了许多其余优点,帮助咱们更快地添加功能。github
使用 GraphQL 架构的先后对比。数据库
咱们已经在 NodeJS 上运行 GraphQL 差很少六个月了,而且它已经被证明能够显著提升咱们的开发速度和整体提高页面加载性能。这里是自从咱们使用 GraphQL 实践给咱们带来的一些好处。编程
从新分配负载和有效负载优化后端
一般,某些机器比其余机器更适合作一些任务。当咱们添加了 GraphQL 中间层时,GraphQL 服务器仍然须要调用和客户端直接调用的相同的服务和 REST API。如今的区别在于大多数据在同一数据中心的服务器之间流动。这些服务器和服务器之间的调用是很是低延迟和高带宽的,比起直接从浏览器发起网络请求有 8 倍的性能提高。从 GraphQL 服务器传送数据到客户浏览器的最后一段虽然还是一个慢点,但至少减小成单个网络请求。因为 GraphQL 容许客户端只选择它须要的数据,因此咱们最终能够获取明显更小的有效负载。在咱们的应用程序中,页面以前要获取 10M 的数据,如今接收大约 200KB 便可。页面加载变得更快,特别是数据受限在移动网络上,而且咱们的应用使用的内存更少。这些更改确实以提升服务器利用率为代价来执行数据获取和聚合,可是每一个请求所花费的额外一点服务器毫秒时间远比不上更小的客户端有效负载。浏览器
可复用的抽象缓存
软件开发者一般但愿使用可复用的抽象而不是单一目的方法。使用 GraphQL,咱们定义每段数据一次,并定义它与咱们系统中其余数据之间的关系。当消费者应用程序从多个源获取数据时,它再也不须要担忧与数据链接操做相关联的复杂业务逻辑。
考虑接下来的例子,咱们在 GraphQL 中只定义实例一次:catalogs(类别)、creatives(素材)和 comments(评论)。如今咱们能够由这些定义建立多个页面视图。客户端上的一个页面(类别视图)定义了它想要全部的评论和素材在一个分类里,而另外一个客户端页面(素材视图)想要知道素材相关联的类别,以及全部和它相关的评论。
GraphQL 数据模型的灵活性,用于表示来自相同底层数据的不一样视图。
同一个 GraphQL 模型就能够知足上述两个视图的需求,而不用作任何服务器端的代码修改。
链式系统
不少人专一于单一服务器里的类型系统,但很难有跨服务的。一旦咱们在 GraphQL 服务器中定义了实例,咱们使用自动代码生成器工具为客户端程序生成 TypeScript 类型。咱们的 React 组件属性接收类别以匹配组件正在进行的查询。因为这些类别和查询也是针对服务器模式进行验证的,所以服务器的任何重大更改都将被使用该数据的客户端捕获。将多个服务器和 GraphQL 连接在一块儿并将这些检查挂载到构建过程当中,可让咱们在发布代码前捕获更多错误。理想状况下,咱们但愿从数据层一直到客户端浏览器层都是具备类型安全性的。
从数据库到后端到客户端代码的类型安全。
DI/DX — 简化开发
当建立客户端应用程序时广泛须要考虑 UI/UX,可是开发者界面和开发者体验通常只是侧重于构建可维护应用程序。在使用 GraphQL 以前,编写一个新的 React 包装组件须要维护复杂的逻辑,以便为咱们所需的数据发起网络请求。开发者须要关心每部分数据之间的依赖,数据该怎么缓存,以及是否作并发或队列请求,还有在 Redux 的什么位置存储数据。使用 GraphQL 的查询封装(wrapper),每一个 React 组件只需描述它所须要的数据,而后由封装(wrapper)去关心全部这些问题。这样就会是更少的引用代码和更清晰的数据与 UI 之间的关注点分离。这种定义数据获取的模块可让 React 模块更容易理解,而且可以为部分描述文档提供服务知道组件具体在作什么。
其余优点
咱们也留意到其余一些小的优点。首先,若是任何 GraphQL 的查询解析器失败了,已经成功的解析器仍然会返回数据到客户端渲染出尽量多的页面。其次,因为咱们更少的关心客户端模型,后端数据模型就简化了不少,在大多数状况下,只需提供一个 CRUD 接口的原始实体。最后,基于 GraphQL 的查询会自动为咱们的测试进行存根转变,测试咱们的组件也会变得很简单,而且咱们能够把解析器从 React 组件中独立出来进行测试。
咱们迁移到 GraphQL 是一个直截了当的过程。咱们构建的大多数用于作网络请求和传输数据的基础架构在不作任何代码修改的状况下能够很容易在 React 应用和咱们 NodeJS 服务之间作到可传递。咱们甚至最终删除的代码比咱们加的多。可是在迁移到任何新的技术这条路上,总会有一些须要咱们越过的障碍。
自私的解析器
因为 GraphQL 里的解析器定义为独立运行的单元,而不用关心其余解析器在作什么,咱们发现他们会对相同或相似的数据发起不少重复的网络请求。咱们经过将数据提供者包装在一个简单的缓存层中来避免这种重复,该缓存层将网络响应存储在内存中,直到全部解析器都完成。缓存层还容许咱们将多个对单个服务的请求聚合为一次对全部数据的批量请求。解析器如今能够请求他们须要的任何数据,而没必要担忧如何优化获取数据的过程。
添加缓存以简化来自解析器的数据访问
咱们编写的繁杂网络
抽象是提升开发人员效率的好方法 —— 直到出现问题为止。毫无疑问,咱们的代码中会有bug,咱们不想用中间层混淆(bug 产生的)根本缘由。GraphQL 将自动编排对其余服务的网络调用,对用户隐藏复杂性。虽然服务器日志提供了一种调试方法,可是它们仍然比经过浏览器的 network 选项卡进行调试的天然方法少了一步。为了让调试更简单,咱们直接将日志添加到 GraphQL 响应有效负载中,它公开了服务器发出的全部网络请求。当启用调试标志时,你将在客户端浏览器中得到与浏览器直接进行网络调用时相同的数据。
拆分类型
传递对象是面向对象编程(OOP)的所有,但不幸的是,GraphQL 将对这个范式形成冲击。当咱们获取部分对象时,这些数据不能用于须要完整对象的方法和组件中。固然,你能够手动强制转换对象并抱着最好的但愿,可是你将失去类型系统的许多好处。幸运的是,TypeScript 使用了 duck typing(译者注:鸭子类型,关注点在于对象的行为,能做什么;而不是关注对象所属的类型。duck typing),因此只须要对它们真正须要的对象属性方法进行调整是最快的修复方式。虽然定义更精确的类型须要作更多的工做,可是整体上确保了更大的类型安全性。
咱们仍然处于探索 GraphQL 的早期阶段,但到目前为止都是一种积极的体验,咱们很高兴可以接受它。这项工做的一个关键目标是,随着咱们的系统变得愈来愈复杂,(它)帮助咱们提升开发速度。咱们不但愿被复杂的数据结构所困,而是但愿在图形数据模型上进行投资,随着时间的推移,随着更多的边缘和节点的添加,咱们的团队会更加高效。甚至在过去的几个月里,咱们已经发现咱们现有的图形模型已经足够健壮,咱们不须要任何图形更改就能够构建一些特性。它确实让咱们变得更有效率。
咱们的可视化 GraphQL 模型
随着GraphQL的不断发展和成熟,咱们期待能够从社区中使用它构建和解决的全部使人惊叹的东西中学习。在实现级别上,咱们期待使用一些很酷的概念,好比模式缝合,它可使与其余服务的集成更加直接,并节省大量开发人员的时间。最重要的是,咱们很开心地看到在公司不少团队发现 GraphQL 的潜力并开始采用它。
若是你已经作到了这一点,而且你也有兴趣加入 Netflix 营销技术团队来帮助克服咱们独特的挑战,看看咱们页面上列出的空缺职位。
咱们正在招聘!
若是发现译文存在错误或其余须要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可得到相应奖励积分。文章开头的 本文永久连接 即为本文在 GitHub 上的 MarkDown 连接。
掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 Android、iOS、前端、后端、区块链、产品、设计、人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划、官方微博、知乎专栏。