文档章节

GraphQL 在 HTTP/2 世界中仍然有意义吗?

红薯
 红薯
发布于 11/07 10:37
字数 2488
阅读 3441
收藏 21

大约一周前,Phil Sturgeon 的这则推文激起了许多 GraphQL 爱好者的关注。

相关上下文:https : //apisyouwonthate.com/blog/lets-stop-building-apis-around-a-network-hack

大约在同一时间,创建了这个名为 Vulcain 的项目。(这看起来还不错!)公告的一部分包括“ 您不再需要#GraphQL!”。 最后,马克·诺丁汉(Mark Nottingham)本周发表了一篇精彩的文章 HTTP/2的功能及其对API设计的意义。

这些文章以及项目让我开始思考这么一个问题:当世界上的一切开始运行 HTTP/2( 或者 HTTP/3)时,我们还有什么理由使用 GraphQL?

首先让我们了解 HTTP/2 哪些内容将改变 GraphQL 。HTTP/2 中有很多新特性,例如新的二进制格式和更好的 HTTP Header 压缩,但是在 GraphQL 上下文中让我们谈论的最有意义的事情是 HTTP/2 处理请求/回应。

打开 TCP 连接是许多HTTP/1客户端都希望避免的昂贵操作。出于这个原因,开发人员经常因其大量开销而试图限制请求的数量,例如批处理,查询语言,内联CSS/JS,sprite 等。HTTP/1.1试图通过持久连接解决其中的一些问题和 HTTP 流水线 技术。这两件事允许浏览器通过同一连接发送多个请求和响应。问题是这很容易受到 HTTP Header 阻塞的影响,这意味着一个缓慢的请求可能会使它后面的其他所有请求变慢。而设计 HTTP/2 的聪明人以不同的方式解决了这个问题:与这个新的二进制协议一起出现了新的交付策略。HTTP/2打开单个连接,但是使用新的二进制框架层多路复用请求和响应,其中每个帧都是 流。 然后,客户端和服务器便能够重建每个帧上存在的请求和响应流编号。这使得 HTTP/2 可以通过单个连接非常有效地处理许多请求

不仅如此,HTTP/2 还具有一个称为服务器推送的新概念无需过多赘述,服务器推送允许服务器在客户端请求响应之前抢先发送响应。最好的例子是样式表和JavaScript资源。在响应HTTP请求时,服务器可以检测到正在渲染的HTML页面,其中包含样式表,并且可以预测以下对 CSS 样式的请求,并且已经在客户端请求之前发送了响应。这就是Vulcain,我们在本文开头所讨论的项目就是用来有效地获取链接的资源。

是不是很酷?但这与 GraphQL 到底有什么关系?

GraphQL:单个请求即可全部搞定

GraphQL 的部分吸引力在于,它可以帮助我们更好地处理那些昂贵的 HTTP/1 连接。这是因为 GraphQL 可以让客户端在一次请求回应中即可从获取来自多个服务的响应数据。将此与以超媒体为中心的 API 进行比较,后者通常需要大量的网络请求(某些缓存可以提供帮助)。

https://graphql.org/ 将此特性用作“亮点”。

大多数宣称 GraphQL 对 HTTP/2 无效的人都在谈论这一点。如果发出请求的成本变小,那么从这种意义上讲,批处理API,诸如 GraphQL 之类的查询语言,嵌入式关系以及更大的自定义端点将变得不那么有吸引力了,这是完全正确的!但这是我们使用 GraphQL 的唯一原因吗?我不这么认为。

陷阱:HTTP/2客户端和某些应用程序服务器仍处于早期阶段

这不是一个很好的借口,但值得一提。在某些生态系统中,在应用程序层使用HTTP/2远未解决问题。你可以试试在 Google 上搜 Rack/Rails over HTTP/2 就可知一二。因为许多应用程序服务器都是使用请求/响应模式构建的,并且实现 HTTP/2 流模式并非容易的事,尤其是对于某些框架而言。但是,这不是一个很好的借口,许多生态系统确实为它提供了良好的支持,并且从理论上讲,我们仍然应该致力于使其变得更好!(尽管大多数代理服务器都支持它,但是如果应用服务器陷入这种请求/响应模式,则很难执行服务器推送之类的操作。)

GraphQL不仅涉及减少往返请求或关于过度/不足的获取

尽管我们看到这两个特性被大量的宣传,但 GraphQL 不仅为我们提供了减少往返请求或减少通过网络传输的字节数的功能。

GraphQL 的功能以及最大的折衷之处就是它以客户为中心。在过去的几年中,这在很多人的心中是一个令人担忧的问题。丹尼尔·雅各布森(Daniel Jacobson)在5到7年前就其中一些问题写了许多惊人的文章。这是另一篇文章

我们的 REST API 虽然非常有能力以通用方式处理来自我们设备的请求,但并未针对其中的任何一个进行过优化。

请注意,这并不一定与 REST 需要我们发出更多请求或传输不必要的数据有关。更多有关设计 API 的信息,该 API 支持多种不同的客户端用例。解决此问题的一种常见方法是让客户端逻辑更接近服务器,例如2012年该帖子中提到的Netflix的客户端适配器。从那时起,他们的一些团队甚至一直在使用GraphQL。该BFF模式是另一个抽象,旨在解决类似的问题。

GraphQL 通过帮助我们构建能够将客户端用例编译为服务器资源的服务器引擎,重新定义了客户端服务器边界。持久查询使这更容易理解,本质上是客户端生成的服务器资源。

作为服务器端抽象的 GraphQL 在讨论它在HTTP/2世界中是否仍然有意义时要牢记。尽管维护各种用例可能会导致典型的基于终结点的 API 出现问题,但GraphQL 使 API 提供程序可以专注于公开更多的可能性,而无需考虑现有客户端的成本,也不必增加维护大量不同资源的复杂性。(它的确增加了成本:难以优化性能;并非总是可缓存的。这个经常需要在高度可定制的API中进行同样的权衡取舍)

客户端开发人员经验

在这些文章中,我倾向于将重点放在服务器端的内容上,但是要提醒自己的是 —— GraphQL 在客户端级别上尤其受欢迎!将 GraphQL 片段与我们在现代前端框架中看到的组件模式配对时,绝对是很棒的做法。同样,与持久查询配合使用,GraphQL客户端开发人员的体验可能会非常令人难以置信的棒。

整个包装使它变得很棒

GraphQL 并没有什么特别之处,而且是可以替代的技术。Typed Scheme?只需使用OpenAPI!服务器端抽象来处理多个客户端用例?有很多方法可以做到这一点。内省?超媒体可以允许客户端发现操作,也可以从根开始。惊人的GraphiQL?我确定OpenAPI会有帮助。始终可以重新创建GraphQL的部分内容。但是,在一个规范下找到的这一切,使GraphQL具有吸引力,并且对我们许多人来说都很棒。我怀疑这也是促使它增长如此之快的原因。关于构建 API 风格有很多指导,而且针对 GraphQL 语言特定的库往往质量很高且被广泛采用。

网络仍然是(永远是?)的约束

这是最后一个问题。无论网络请求有多快,它们似乎总是会受到某种约束。这就是为什么我们不像典型的编程语言对象那样设计Web API的原因: 

企业应用程序体系结构模式的摘录:https : //martinfowler.com/books/eaa.html

虽然 HTTP/2 绝对支持更细粒度的请求,但我认为这种权衡仍然存在。

HTTP/2 可以帮助 GraphQL 吗?

尽管 GraphQL 给我们带来了许多其他重要的东西,但是 HTTP/2 仍然很棒。将来可能要考虑的事情是,我们是否也可以将这种功能带给GraphQL。像这样:

query {
  viewer {
    name
    posts(first: 100) @stream {
      title
    }
  }
}

我们仍然可以在使用HTTP/2流的同时使用GraphQL的服务器端抽象,它是声明性查询语言。Facebook 已经在使用 WebSocket 上进行了探索。我们需要更多的探索,我需要看看这个多,但我知道很多人已经在用一些指令,如@defer@stream@live

最后的话

HTTP/2 非常棒,尤其是本文中的示例令人震惊!如果 GraphQL 只是减少请求响应的往返次数或节省字节数的一种方法,那么您可能会对 HTTP/2 更满意,但是,如果您还感受到了本文中讨论的其他功能,那么你会意识到 GraphQL 给我们带来的不仅仅这些。

本文译自 Marc-André Giroux  ,感谢您阅读!

© 著作权归作者所有

红薯

红薯

粉丝 22070
博文 157
码字总数 82916
作品 8
深圳
产品经理
私信 提问
加载中

评论(2)

善良超哥哥
主流的爬虫库和框架都没开始支持HTTP2
依剑_听雨
依剑_听雨
用下 ApolloGraphql 和 prisma ,你会对 graphql 产生新的认识。
API 接口设计: GraphQL 和 REST 怎么选择?

文章转发自专业的Laravel开发者社区,原始链接:learnku.com/laravel/t/2… 这个话题在开发社区里已经讨论过一段时间,人们对此有不同的看法与观点,那么我应该使用哪一个? 有很多东西需要成...

Summer__
10/01
0
0
用Node.js创建安全的 GraphQL API

翻译:疯狂的技术宅 www.toptal.com/graphql/gra… 本文的目标是提供关于如何创建安全的 Node.js GraphQL API 的快速指南。 你可能会想到一些问题: 使用 GraphQL API 的目的是什么? 什么是...

前端先锋
05/07
0
0
在vue项目中集成graphql(vue-ApolloClient)

1.什么是graphql GraphQL 是一个用于 API 的查询语言,是一个使用基于类型系统来执行查询的服务端运行时 下图展示graphql所处的位置 2.优点 1.GraphQL API 有强类型 schema GraphQL schema是...

peakedness丶
2018/11/09
137
0
写一个GraphQL的小demo

写一个GraphQL的小demo 原教程(https://juejin.im/post/5a49e5ccf265da430d585cfd),本帖主要记录遇到的坑以及暂时的解决方法,顺便为以后的升级做准备 原教程 原教程写的挺好,使得我一个从...

zust_hhhh
2018/09/26
0
0
记一次通过c#运用GraphQL调用Github api

阅读目录 GraphQL是什么 .net下如何运用GraphQL 运用GraphQL调用Github api 结语 一、Graphql是什么   最近在折腾使用Github api做个微信小程序练练手,本篇文章就是在这个过程中记录。  ...

ZacharyZF
2018/07/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Kafka实战(五) - 核心API及适用场景全面解析

1 四个核心API ● Producer API 允许一个应用程序发布一串流式的数据到一个或者多个Kafka topic。 ● Consumer API 允许一个应用程序订阅一个或多个topic ,并且对发布给他们的流式数据进行处...

JavaEdge
21分钟前
5
0
实现线程的第三种方式——Callable & Future

Callable Runnable 封装一个异步运行的任务, 可以把它想象成为一个没有参数和返回值的异步方 法。Callable 与 Runnable 类似, 但是有返回值。Callable 接口是一个参数化的类型, 只有一 个...

ytuan996
今天
8
0
OSChina 周六乱弹 —— 不要摁F了!

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @巴拉迪维 : 朴树写的词曲都给人一种莫名的失落感,不过这首歌他自己却没有唱,换成赵传这种高音阶嘶喊的确很好,低沉但却有力,老男人的呐喊...

小小编辑
今天
10
0
Android Binder机制 - interface_cast和asBinder讲解

研究Android底层代码时,尤其是Binder跨进程通信时,经常会发现interface_cast和asBinder,很容易被这两个函数绕晕,下面来讲解一下: interface_cast 下面根据下述ICameraClient例子进行分析...

天王盖地虎626
昨天
12
0
计算机实现原理专题--存储器的实现(二)

计算机实现原理专题--存储器的实现(一)中描述了一种可以记住输入端变化的装置。现需要对其功能进行扩充,我们将上面的开关定义为置位,下面的开关定义为复位,然后需要增加一个保持位,当保...

FAT_mt
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部