GraphQL在HTTP / 2时代是否失去了相关性?

Phil Sturgeon最近发布了一条推文 ,极大地吸引了GraphQL粉丝。 该推文讨论了GraphQL的定义,该技术与HTTP / 2的本质相矛盾。 HTTP / 3标准已经发布,并且该推文的作者并没有真正理解选择GraphQL会走不兼容之路的事实。 为了更好地理解Phil对于GraphQL态度的原因,请查看材料。



大约在同一时间,发布了有关Vulcain项目的公告。 此消息包含以下单词:“ TL / DR:不再需要GraphQL!”。 最后,Mark Nottingham撰写了一篇很棒的文章,内容涉及HTTP / 2的强大功能以及这些功能对设计API的人意味着什么。 Darrel Miller与他的订阅者共享了此文章链接。

发生的事情使我想到了GraphQL和HTTP / 2。 如果一切都开始使用HTTP / 2(和HTTP / 3)开始工作,这是否意味着我们没有理由使用GraphQL? 我今天想知道。

HTTP / 2创新


首先,让我们弄清楚在开发人员眼中HTTP / 2技术中哪些因素会影响GraphQL的价值。 HTTP / 2提供了很多功能。 例如,这是一种新的二进制格式和改进的头压缩。 但是在我们的案例中,主要角色是使用HTTP / 2时如何处理请求和响应的传递。

打开TCP连接是一项昂贵的操作。 使用HTTP / 1的客户端往往不会经常运行它。 由于这个原因,由于系统上的大量额外负载,开发人员经常试图通过诉诸各种技术来限制请求的数量。 例如,这执行批处理查询,使用查询语言,在页面代码中嵌入CSS / JS代码,使用精灵表而不是单个图像等等。 在HTTP / 1.1中。 试图使用持久连接和流水线数据处理来解决其中的一些问题。 这两种技术允许浏览器在同一连接中发送多个请求,并接收对它们的答复。 这种数据交换方案的缺点在于,它存在阻塞队列开始的问题( Head-of-line阻塞 )。 这个问题体现在一个缓慢的请求可能会减慢其后所有请求的处理速度这一事实。 使用HTTP / 2的专家提出了解决此问题的不同方法。 HTTP / 2与新的二进制协议一起引入了新的数据传递策略。 在使用HTTP / 2协议的系统交互过程中,将打开一个连接,在该框架内,当每个帧是流的一部分时,将使用设计用于帧的新二进制级别执行请求和响应的多路复用。 使用此机制,客户端和服务器可以基于帧中有关它们的信息来重新创建请求和响应流。 这允许HTTP / 2非常有效地支持在单个连接中执行的许多请求的处理。

但这还不是全部。 HTTP / 2具有一个称为服务器推送的新概念。 如果您不详细介绍,那么我们可以说该技术允许服务器在客户端请求此数据之前预先将数据发送给客户端。 此行为最引人注目的示例是预先向客户端发送样式表和JavaScript资源。 在生成对HTTP请求的响应的过程中,服务器可以发现需要特定的CSS文件来呈现HTML页面,并且可以预先确定客户端将很快就该文件与他联系。 这允许服务器甚至在客户端请求文件之前将给定文件发送给客户端。 这就是上述Vulcain项目的工作方式,使用该技术来组织相关资源的有效加载。

因此,尽管一切都清楚了。 但是,这与GraphQL有什么关系?

GraphQL:一个可以解决所有问题的查询


GraphQL技术的部分原因在于它的吸引力,因为它可以帮助开发人员应对HTTP / 1连接的典型缺点。

这就是GraphQL允许客户在一个会话中与服务器进行通信来满足接收几乎所有内容的请求的原因。 与Hypermedia-API相比,使用Hypermedia-API时通常需要执行许多网络请求(但是,有时缓存可以改善这种情况)。


能够在单个查询中接收多个资源的能力是GraphQL的优势之一 ,这项技术的创建者吸引了它的潜在用户的注意力。

许多说HTTP / 2出现的人都不需要GraphQL技术意味着这种可能性。 使用批处理API,查询语言(例如GraphQL),优化关系,甚至创建聚合的端点,现在看起来都没有以前那么吸引人了。 问题是执行查询的“成本”变小。 那是真的。 但这仅仅是为什么我们使用GraphQL吗? 我不这么认为。

也许事实是,现在仍是HTTP / 2客户端和某些服务器应用程序的早期时代?


对于我们仍在广泛使用GraphQL这一事实,我认为本节标题中提出的问题不能作为一个有价值的解释。 但是值得一提。 在某些生态系统中使用应用程序级HTTP / 2是一个挑战,远远没有解决。 例如,查找单词“ HTTP上的Rack / Rails / 2”。 会很有趣。 问题是应用程序的许多服务器部分都是使用请求/响应模式构建的。 结果,切换到HTTP / 2流的概念并不是那么简单。 特别是在某些框架的情况下。 但这是一个不值得的借口,许多生态系统完全支持客户端和服务器之间的这种交互方案,并且从理论上讲,我们仍应努力改善这种交互。 (大多数代理服务器也支持此功能,但是如果服务器应用程序过去使用请求/响应模式被卡住,则很难组织诸如主动向服务器发送数据到客户端的事情)。

GraphQL不仅可以减少接收和传输数据的时间,或者可以优化传输的信息量


尽管减少和减少数据的接收和传输时间并优化传输的信息量是我们不断听到的GraphQL的优势,但这项技术为我们提供了更多信息。

GraphQL技术的强大之处在于它专注于客户端系统。 客户端是GraphQL做出许多妥协的环境。 近年来,这困扰了许多人。 因此,丹尼尔·雅各布森(Daniel Jacobson)在5到7年前就其中一些问题写了很多很好的文章。 在这里那里 -他的一些出版物。 他在其中之一中说:“尽管我们的REST API能够处理一般请求,但并未针对这些请求中的任何一个进行优化。”

请注意,这种想法不仅适用于REST技术,而且是有效的。 客户端应用程序通常必须执行比其开发人员所希望的更多的服务器请求。 这些应用程序必须处理从服务器接收不必要的数据。 这更多是关于设计易于创建的API,以便它们支持许多不同的用途。 解决此问题的通常方法是使客户端逻辑与服务器逻辑尽可能接近。 这种方法的一个示例是 2012年文章中提到的Netflix客户端适配器。 从那时起,一些Netflix团队甚至改用 GraphQL。 BFF模式也旨在解决此类问题。

GraphQL技术正在改变客户端和服务器之间边界的概念,帮助我们创建服务器系统,其中可以包含有关客户端将如何使用它们的信息。 当使用持续请求技术时,这一点很明显地体现出来,因为在这里,我们实质上是在谈论由客户端发起的服务器资源。

在考虑GraphQL在HTTP / 2世界中的相关性时,请记住我们在谈论服务器抽象。 支持各种服务器数据用例可能会导致传统的基于端点的API出现问题。 GraphQL允许那些支持API的人专注于为这些API的用户提供广泛的功能。 同时,API的所有者可能不必担心现有客户端上不断增加的负载,并且由于需要支持许多不同的资源,因此对API的支持将变得更加复杂。 (支持许多不同的资源有其缺点。因此,此类方案使性能优化复杂化。此类资源并非总是被很好地缓存。可以大量调整的API也会遇到相同的问题)。

客户端系统和GraphQL开发


在本文中,我主要讨论服务器,但是重要的是要记住,客户端开发人员非常喜欢GraphQL技术。 如果将GraphQL片段与现代前端框架中的组件方法相结合,您将获得完全令人惊叹的抽象。 同样,如果我们在此处添加常量查询,则可以说GraphQL使客户端系统的开发人员的工作更加轻松。

GraphQL是具有卓越功能的整体系统


GraphQL并非具有完全独特的功能。 该系统还有其他选择。 键入方案? OpenAPI也是如此! 支持不同客户端用例的服务器抽象? 这可以通过多种方式实现。 内省? 使用Hypermedia可使客户端发现操作并开始使用根实体。 美味的GraphiQL工具? 我确定为OpenAPI创建了类似的东西。 总是可以使用其他技术来重新创建GraphQL的可能性。 但是,GraphQL是一个整体系统。 这就是吸引大量乐于使用此系统的GraphQL开发人员的原因。 我怀疑这是GraphQL迅速普及和发展的原因之一。 此外,由于GraphQL-API的构造已得到充分证明,因此为不同语言设计的GraphQL库通常具有很高的质量和知名度。

网络仍然是一个限制因素(或者也许永远都是这样?)


这是我想继续谈的另一种想法。 感觉到,在使用API​​时,网络将始终扮演某些限制因素的角色。 网络请求有多快都没关系。 这就是为什么我们不以与不同编程语言中使用的普通对象相同的方式来设计Web API的原因。 例如, 在这里 ,我们谈论的是为什么具有高细节水平的接口不太适合创建用于与其远程工作的系统。

虽然HTTP / 2绝对鼓励以高粒度执行请求,但我认为这里需要进行一些权衡。

HTTP / 2可以帮助GraphQL吗?


因此,GraphQL为开发人员提供了许多重要且有用的工具,但是HTTP / 2也是一项很棒的技术。 让我们展望未来,并思考GraphQL系统可以从使用HTTP / 2中受益。 例如,它可能看起来像这样:

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

事实证明,我们可以很好地使用GraphQL的服务器端抽象(该技术的声明性查询语言),并同时使用HTTP / 2流的功能。 我认为这里使用了网络套接字。 我仍然需要弄清楚这一点,但是我确信很多人已经在探索GraphQL指令,例如@live @stream@live @stream@stream

总结


HTTP / 2是一项很棒的技术( 这里给出的示例只是某种奇迹)。 GraphQL只能被视为一种减少客户端与服务器之间的通信会话数量或帮助优化传输数据量的技术。 如果是这样,那么从相似的角度来看GraphQL的任何人都会很高兴使用基于HTTP / 2功能的API。 但是,如果您在GraphQL中看到了可以为开发人员提供许多有用功能的多种技术组合,则很显然GraphQL的功能完全不限于改善网络资源的使用和节省流量。

亲爱的读者们! 如果您使用GraphQL技术,请告诉我们您最不喜欢它的地方。


Source: https://habr.com/ru/post/zh-CN472340/


All Articles