随笔 - 290  文章 - 10  评论 - 85  2

在刚开始时,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——简化开发

posted on 2018-12-29 17:05  Gu  阅读(...)  评论(...编辑  收藏