【AICon】探索八个行业创新案例,教你在教育、金融、医疗、法律等领域实践大模型技术! >>> 了解详情
写点什么

GraphQL 最突出的架构优势是什么?

  • 2021-03-29
  • 本文字数:4255 字

    阅读完需:约 14 分钟

GraphQL 最突出的架构优势是什么?

在服务器上使用 GraphQL 代替 REST 是有很多好处的,使用 Apollo Client 取代自己编写的数据获取逻辑也有很多优势。在这篇文章中,我们主要讨论 GraphQL 最突出的架构优势。


本文最初发布于 khalilstemmler.com 网站,经原作者授权由 InfoQ 中文站翻译并分享。


在过去的几年中,我们已经看到各种规模和形态的公司都开始在整个组织中逐渐采用 GraphQL,例如 Expedia、Nerdwallet 和 Airbnb。在本文中,我们将讨论在未来或现有的项目中使用 GraphQL 都将享受哪些架构优势。

六边形架构


Alistair Cockburn 在“六边形架构”中提到,我们架构的最内层是应用程序和域层。在这一层的外面是适配器(或端口)。


可以将端口视为“将外部世界连接到内部世界的一种方式”。外部世界有很多技术,我们可以在其之上构建应用程序。在外部,你能找到数据库、外部 API、云服务和种种内容。如果我们采用依赖倒置方法,就可以定义一些端口来将它们安全地包含在我们的应用程序中。端口是抽象、合约。它们通常以 接口抽象类 的形式出现。



Alistair Cockburn 的“六边形架构”


我非常赞同这种类型的架构,因为它使我们能够:


  • 直到真正有必要做出决策时,才决定到底采用哪种类型的 Web 服务器、数据库、事务电子邮件提供商或缓存技术。在开发工作早期,我们完全可以使用一个端口的内存内实现。

  • 通过依赖注入方法,这种架构还会让开发人员优先编写可以测试的代码。这样我们就可以尽可能地减少可能导致代码不可测试的具体依赖项。

  • 最后,它将我们的关注点转向了应用程序和特定于域的内容。这些内容是不能直接从市场购买或下载的。

基础架构组件


GraphQL 服务器和 HTTP 服务器都属于基础架构组件。


基础架构组件:构成 Web 应用程序基础的基本组件。根据整洁(或六边形)架构的思想,数据库、Web 服务器和缓存都是外层基础架构组件。


我们之所以将基础设施组件称为基础设施,是因为 我们会在它们的基础上构建应用程序。在这一基础(即框架)内,我们编写丰富的、领域特定的应用程序。基础设施只是驱动程序而已。


基础架构组件的另一个主要特征是,它们不是我们项目开发工作的重心


基础架构组件是业界信任的一系列工具,我们只需对其配置即可使其正常工作。


GraphQL API 的配置工作包括:


  • 安装 GraphQL

  • 公开一个服务器端点

  • 设计一个模式(schema)

  • 将解析器连接到数据源


这是我们需要做的工作,但不是我们项目的工作重心


如果某项基础架构技术受到业界的信任,我们就可以选择用这种工具来完成任务,而不是开发自己的基础架构组件,这样就可以加快我们的开发速度。


考虑数据库。它们也是基础设施。


例如,Postgres 数据库是我们可以用于新项目的几个数据库选项之一。想象一下,如果你试图说服你们的团队,你们的项目应该从头开始编写自己的数据库,其他人会有多么大的反对声。


如果有人说团队应该从头开始研发一种持久性存储技术,大家肯定会觉得这样的场面看起来很愚蠢;但选择你的 Web 应用程序 API 样式(传输 / 客户端 - 服务器技术)其实也是一样的道理。


去年(2019 年),我意识到 API 在技术栈中的深度已经超出了我们的想象。API 的触角伸到了前端框架的数据存储,也伸到了后端服务的合约层面。


这听起来可能有点虚幻,但它的确就是那样。在 Apollo GraphQL,我们将这种虚拟层称为数据图。并且 Apollo 构建了很多可提高开发人员生产效率的工具。

数据图


数据图 这个理念我是最早在 2019 年 GraphQL 峰会上听 Apollo GraphQL 的首席技术官 Matt DeBergalis 提出的。我强烈推荐 Matt 在 2019 年 GraphQL 峰会上的演讲,他介绍了数据图的概念。


数据图是虚拟层,位于我们的客户端应用程序和 GraphQL 服务器之间。它保存了整个组织的数据,并提供了用来在整个组织内获取和更改状态的语言


数据图是一个声明性的、自文档化的、组织层面的 GraphQL API。


对我来说,数据图是现代应用程序技术栈中之前 缺少的一个层



基本的全栈 Apollo Client+Server 应用程序栈

数据图让远程状态更接近客户端本地状态


所有前端框架都需要解决的三个挑战分别是数据存储、更改检测和数据流。


React 开发人员通常需要修补 Redux 或 Context,并编写大量样板代码来满足这些要求。


Apollo 发布了带有 apollo-link-state 的 Apollo Client 后,React 开发人员就能用更少的代码满足所有这三个需求了。


Apollo-link-state(现已直接放入 Apollo Client 2 和 3 中)让开发人员可以编写几乎同时解决远程状态和本地状态的查询。远程状态(位于服务器上)感觉比之前近多了。


比如说用这种查询来按照狗的品种(breed)来获取一只狗:


查询 /dog.js


const GET_DOG = gql`  query GetDogByBreed($breed: String!) {    dog(breed: $breed) {      images {        url        id        isLiked @client # signal to resolve locally      }    }  }`;
复制代码


在主要用于获取远程资源的查询中,我们可以使用 @client 指令来引用要基于一个客户端模式从本地缓存中获取的属性。我们可以在同一请求中完成这一操作,这很厉害。想想之前在 Redux 环境我们要执行的 spread 和 Object.assign() 操作的数量有多少,就可以对比出差异了。



简化的数据获取架构,其中视图可以是任意前端框架——nerdwallet


数据图在连接的两端均有 Apollo 服务器和客户端,它可以简化获取逻辑、错误逻辑、重试逻辑、分页、缓存、optimistic UI 以及其他各种类型的样板数据管道代码。



数据图从客户端延伸到服务器,并为现代 Web 应用程序中获取数据和更改状态时面临的最常见基础架构问题提供了答案


为了通过 GraphQL 与后端服务通信,Apollo Client 公开了几种客户端方法,这些方法在被调用时会将操作转换为适当的 API 以跨越数据图。


在 Apollo Server 端,这些 API 调用将控制权转交给负责使用 ORM、原始 SQL、缓存、其他 RESTfulAPI 或任何你想到的方法来获取数据的解析器。对于突变,解析器可以简单地将控制权传递给一个应用层用例。


将用例作为应用程序的重心后,从 REST 切换到 GraphQL(或同时支持两者)变得轻而易举。

GraphQL 是自文档化的


维护 RESTfulAPI 时需要做的一件麻烦事是保持文档及时更新和内容全面。


RESTfulAPI 有两处可以更改。


  • 路由 + 方法组合

  • 请求形式 + 参数


路由 + 方法组合 的一个例子是,某人可以很简单地将 创建一个用户 的操作从 POST /users 移至 POST /users/new。这样的 API 更改可能不会引起注意,却会破坏 API 的所有客户端,并且 API 客户端几乎不可能检测到该组合的更改。


请求形式 + 参数 的一个例子是,一个对 /users/new 的 POST 请求过去只需要一个 email 和一个 password,但现在它还需要一个 username 属性。API 客户端了解如何解决该请求的唯一方法是检查错误响应(指望错误消息描述了所需的信息,否则也没用)。


如果你认为自省(introspection)是全面的文档,那么可以说 GraphQL 是自文档化的,并且你的 API 文档无法失去同步。


使用 GraphQL Playground,可以浏览 GraphQL 端点的所有功能。



由于具备执行自省查询的能力,所以 GraphQL Playground 的 GraphQL 资源管理器可以显示 GraphQL 端点的所有功能


在 REST 领域中,我只看到了使用 Swagger 构建的 API 具有这么大的元数据量。这是一项非常强大的特性,它不仅让代码成为了文档的唯一真实来源,而且为我们提供了通过代码生成来自动创建 TypeScript 类型、客户端库或服务到服务通信的基础。


由于 GraphQL 语言是通行(ubiquitous)且标准化的,因此人类 和机器 会更容易理解如何集成和使用它。

关注点的扩展和分离


GraphQL 原则指出,


“你的公司应该有一个统一的图,而不是让各个团队创建很多图。”


随着越来越多的团队开始使用 GraphQL,公司内部会出现多个图的情况。


使用 Apollo Federation,每个服务团队都可以从其限界上下文中构建和管理自己的 GraphQL 服务,将其注册到一个 Apollo 网关,从而在整个企业中分布化 GraphQL 的运维工作。



通过 Apollo Federation,我们可以绘制并公开由多个 GraphQL 端点组成的单个数据图


在 Federation 中,你可以组成模式并解析其他服务 / 限界上下文中的字段。收到请求时,将从相应的服务中解析这些字段。


对于规模庞大的组织来说,这种需求并不罕见。

单一端点


SOLID 原则中的开闭原则指出:


“组件 / 系统 / 类应对扩展开放,但对修改封闭”。


在架构层面,由于 GraphQL 仅向客户端公开单个端点,因此它满足了这一原则。


客户端隐藏了字段解析机制的所有复杂性,它只需关注如何在 GraphQL 服务器之上构建即可。



该图描述了组织的数据图随时间的演变

扩张前端开发人员的权力


数据图减少了前端开发人员对后端开发人员的依赖,这样前者就可以自行为新的用例开发新的端点。


很多时候,我们对 UI 所做的微小改动也会让我们替换掉组件,或意识到我们错误地判断了数据需求,并且需要为一些组件添加更多字段。因为这种情况经常发生,并且因为 REST 如此严格,所以每当我们需要调整的时候都必须依赖后端团队来更改 REST API。


根据团队的结构,以下每个问题都可能意味着开发人员的生产力下降,并需要依赖后端团队。


  • 团队是碎片化的吗?前端开发人员是只做前端开发,还是允许他们完成技术栈另一端的工作?

  • 你的后端开发人员是否在远程工作?

  • 你的后端开发人员在办公室工作吗?

GraphQL 消除了管理 API 版本的需求


GraphQL 原则在版本控制方面也有很强的见解。它指出:


“模式应根据实际需求逐步构建,并随着时间的推移平稳发展。”


这意味着团队应该通过迭代来做更改,而不是在大版本中一次塞入很多更改,这样就可以实践敏捷模式开发了。


听上去一切都很完美,但是你我都生活在现实世界中。我知道这样理想化的情况并不总是存在,至少没有适当的工具链是不可能做到的


Apollo 平台有一项称为模式验证的特性,可让你针对实时生产流量测试每个更改,并在建议实施重大更改时向你显示提示,让团队可以交流接下来的方案。


这种感觉很顺滑!

总结


  • 在现代 Web 应用程序架构中,GraphQL 和 RESTfulWeb 服务器都是基础架构组件。

  • 基础架构组件是基本组件,它们构成了我们编写的特定领域 Web 应用程序的基础。

  • 基础架构组件并不是大多数 Web 开发项目的重心,因此我们应该将大部分时间用于应用程序和域层代码。

  • 数据图是一个声明性的、自文档化的、组织层面的 GraphQL API,它使远程状态更接近客户端,可以使用 Apollo Federation 来扩展。

  • 前端开发人员可以使用数据图来创建自己的数据获取用例,而不必依赖后端开发人员。

  • GraphQL 消除了管理 API 版本的需要,Apollo 的 GraphManager 可以简化生产模式验证。


原文链接


https://khalilstemmler.com/articles/graphql/graphql-architectural-advantages/

公众号推荐:

跳进 AI 的奇妙世界,一起探索未来工作的新风貌!想要深入了解 AI 如何成为产业创新的新引擎?好奇哪些城市正成为 AI 人才的新磁场?《中国生成式 AI 开发者洞察 2024》由 InfoQ 研究中心精心打造,为你深度解锁生成式 AI 领域的最新开发者动态。无论你是资深研发者,还是对生成式 AI 充满好奇的新手,这份报告都是你不可错过的知识宝典。欢迎大家扫码关注「AI前线」公众号,回复「开发者洞察」领取。

2021-03-29 16:554519

评论

发布
暂无评论
发现更多内容

对于MUI的实现原理以及遮罩蒙版和numbox以及侧滑导航的事件监听的运用和实战

恒山其若陋兮

Vue 前端 11月月更

OceanBase获奖!蚂蚁集团第三次入选世界互联网领先科技成果

OceanBase 数据库

前端开发面试题自测

loveX001

JavaScript

时延测评|免费又好用的低延时远程控制软件竟是它!

RayLink远程工具

远程控制软件 远程办公软件 远控软件 远程桌面连接 RayLink

远程办公软件RayLink公有云版正式上线,专业连接限时免费至12月底!

RayLink远程工具

远程控制软件 远程办公软件 远控软件 远程桌面连接 RayLink

解决APP抓包问题【网络安全】

网络安全学海

网络安全 安全 信息安全 渗透测试 漏洞挖掘

Docker容器的使用

我是一个茶壶

容器 11月月更 docker、

2022 vivo开发者大会人工智能专场:打造「1001个便利」

Geek_2d6073

数据中台选型必读(四):要想中台建的好,数据模型得做好

雨果

数据中台

银行APP用户体验外滩峰会即将开启!四大亮点抢先看

易观分析

金融 银行 易观

Windows下载安装Vue开发者工具(VueDevtools)

不觉心动

Vue 11月日更 11月月更

假如面试官问你Babel的原理该怎么回答

loveX001

JavaScript

Docker 镜像使用

我是一个茶壶

Docker 镜像 11月月更

【kafka运维】 kafka-consumer-groups.sh消费者组管理

石臻臻的杂货铺

kafka kafka运维 11月月更

商家和企业如何选择KOC合作:要明确推广目标、选对平台和博主

石头IT视角

远程控制软件如何像素级还原设计稿色彩?

RayLink远程工具

远程控制软件 远程办公软件 远控软件 远程桌面连接 RayLink

算法题学习---合并k个已排序的链表

桑榆

算法题 11月月更

中国数据中台未来会怎样?三个趋势预测为您指明方向

雨果

数据中台

常用硬件接口知识

智趣匠

RS232、RS485 11月月更 硬件接口 VGA

2022-11-09:给定怪兽的血量为hp 第i回合如果用刀砍,怪兽在这回合会直接掉血,没有后续效果 第i回合如果用毒,怪兽在这回合不会掉血, 但是之后每回合都会掉血,并且所有中毒的后续效果会叠加 给

福大大架构师每日一题

算法 rust 福大大

2022 VDC安全隐私专场:提升用户产品安全体验,携手伙伴共建安全新生态

Geek_2d6073

20道前端高频面试题(附答案)

loveX001

JavaScript

非行稳无以致远:华为如何写好数字金融的大文章?

脑极体

MUI框架之移动端前端开发对dialog与button轮播的深入运用与实战

恒山其若陋兮

Vue 前端 11月月更

MUI实战之switch和事件以及transparentBar与slide的实战与深入运用

恒山其若陋兮

前端 11月月更 黎燃

【愚公系列】2022年11月 微信小程序-app.json配置属性之window

愚公搬代码

11月月更

2022 VDC应用与服务专场:帮助开发者实现增长共赢

Geek_2d6073

Websocket集群解决方案

Jeremy Lai

websocket 集群 发布订阅模式

WiFi、蓝牙、NFC 哪家强?短距离无线通信技术对比分析

元器件秋姐

无线通信 元器件选型 元器件电商平台 元器件采购

漫游Hadoop(一):NameNode公平队列

冰心的小屋

hadoop hdfs

详解typora配置华为云图床

乌龟哥哥

11月月更

GraphQL 最突出的架构优势是什么?_语言 & 开发_Khalil Stemmler_InfoQ精选文章