当前位置:网站首页>为什么我们不使用GraphQL? - Wundergraph
为什么我们不使用GraphQL? - Wundergraph
2020-11-09 00:39:00 【解道jdon】
我认为GraphQL将改变世界。将来,您可以使用GraphQL查询世界上的任何系统。我正在建立这个未来。那么,为什么我反对使用GraphQL?
我个人的烦恼是,当前社区采取GraphQL的理由实际上与GraphQL无关。如果我们想推动采用,我们应该诚实并脱掉玫瑰色的眼镜。这篇文章是对Kyle Schrade的“为什么使用GraphQL”的回应(https://www.apollographql.com/blog/why-use-graphql/),我并不是要直接批评该文,我认为Kyle的文章应命名为“为什么使用Apollo”。
REST缺点
作者指出REST API具有一些缺点,以及GraphQL如何解决所有这些缺点:过度获取多个资源的多个请求,会产生基于嵌套数据上的瀑布网络请求,要获得这些嵌套数据,每个客户端都需要访问提供这些嵌套数据的每个服务。
解决过度请求可以通过编写另一个REST API作为特定用户界面的外观来解决。以Next.JS为例。接下来,您可以使用非常轻量级的语法来定义API。您可以将这些调用包装到API中并使它们在服务器端,而不是从客户端发出多个请求。
使用这种方法也可以解决过度获取和不足获取,因为您可以在将数据发送回客户端之前对其进行操作。所描述的模式称为“后端的前端”(BFF)。它不限于Next.JS之类的完整堆栈框架。您也可以为移动应用程序构建BFF。
使用BFF模式,客户端本身不必知道每个服务的位置。但是,实施BFF的开发人员需要了解服务格局。希望您对所有服务都有开放的API规范,并在开发人员门户中很好地介绍了这些规范。如果做到这样地步,编写BFF应该很容易。
使用GraphQL,仍然需要一个实现解析器的开发人员。实现解析器与构建BFF差不多是相同的任务,其逻辑非常相似。那么,真正的区别是什么?
BFF易于实现,因为有更多可用的工具。例如,如果将Next.JS之类的框架与swr挂钩(重新验证时失效)结合使用,则可以自动使用Etags进行缓存,并且可以使缓存失效。这减少了服务器和客户端之间发送的数据量。与GraphQL相比,它的数据更少,因为您没有发送查询有效载荷,并且如果响应仍然有效,服务器将以304(未修改)进行响应。此外,您不必使用像Apollo这样的重量级客户端。Vercel的库swr很小,非常易于使用。它带有对分页,挂钩的支持,并有助于非常有效地来回导航。
GraphQL保留了查询,但是要实现这一点会带来额外的开销。如果您没有使用像Relay这样的客户端(默认情况下会保留查询),则必须自己完成操作或使用第三方库来实现它。与使用Next.JS的BFF方法相比,在前端获得相同结果要涉及更多的复杂性。您将如何使用GraphQL实现Etags?如果未做任何更改,如何使GraphQL服务器返回304状态代码?您不是首先必须将所有查询都转换为GET请求吗?如果是这样,您的GraphQL客户端和服务器是否轻松支持此功能?
在用户体验和易于开发方面,BFF无疑是赢家。客户端和服务器之间的数据传输更少。易于实施。客户更小,活动部件更少。
但是有一个陷阱。您必须为每个前端构建一个BFF。如果您有很多,那么可能会需要很多工作。您必须维护所有BFF。您必须对其进行操作。您必须保护它们。
如果您在不进行折衷的情况下同时获得两者的好处,那岂不是很好吗?这正是WunderGraph的含义,它是使用GraphQL构建BFF的框架。
没有更多的版本的API
在下一段中,Kyle继续探讨版本API所涉及的问题。他绝对正确,因为API版本过多会使跟踪变得非常困难。然后他得出结论,在GraphQL中,只有一个版本的图形,并且可以在架构注册表中跟踪更改,这是Apollo的付费功能。因此,您不会在版本控制方面遇到任何问题,他说。
我很难得出相同的结论。仅仅因为GraphQL模式本身不支持版本控制,并不意味着问题就消失了。如果您不对REST API进行版本控制,则将获得相同的效果。实际上,许多专家说,如果不需要也应该始终不要尝试引入API版本。话虽这么说,是什么让您无法运行两个版本的GraphQL模式?我并不是说这是个好主意,但在技术上是可行的。
如果您的组织中存在太多的REST API版本问题,那么在抛出类似GraphQL之类的新工具之前,也许您应该首先看一下组织。有这么多版本的原因是什么?也许流程的改变或新的团队结构会有所帮助?GraphQL绝对不会解决您的版本问题。相反,我认为这实际上使情况变得更糟。
您必须支持移动应用程序吗?您应该意识到,交付本地应用程序需要时间。您必须等待应用商店的批准,并且可以期望许多用户从不(或缓慢地)安装新版本。如果您想在不破坏客户的情况下在这种情况下进行重大更改怎么办?不可能。您必须以不间断的方式引入此类更改。
在GraphQL的情况下发展模式将意味着您不赞成使用旧字段并添加新字段。新客户使用新字段,而您希望使用旧字段的客户数量会越来越少。希望您拥有一个可以迫使您的用户在某个时间点下载新版本的系统。否则,您可能会被迫无限期地支持不推荐使用的字段。如果是这种情况,GraphQL的弃用模型根本无法帮助您。
使用REST,您可以创建一个新的端点或现有端点的另一个版本。问题是一样的,解决方案看起来有点不同。
明确地说,如果您无法控制客户那边的开发,则就确实需要某种版本控制。如果您只有一个Web应用程序,则不需要此功能。但话又说回来,GraphQL可能也太过杀手了。
更小的载荷
在本段中,原文作者Kyle声称RESTful API不允许部分响应。
这是错误的。这是一个例子:
GET /users?fields=results(gender,name) |
作者Kyle实际上是什么意思?我很确定他知道部分回应。我想他想说的是某人需要实施部分响应。实际上,当您从资源中选择子字段时,它对于GraphQL看起来非常熟悉。使用GraphQL,我们可以立即使用此功能。
另一方面,使用BFF方法,则不需要此方法。只需准确返回所需的数据即可。同样,像Next.JS这样的全栈框架使实现此过程更简单,使缓存更加容易,并且使您免费获得基于Etag的缓存失效。
总结本节,GraphQL可以为您提供所需的确切数据。部分响应可以达到相同的结果。BFF附带了实施和维护的额外费用,但具有更好的UX和DX。
严格类型接口
在本段中,Kyle解决了未严格键入REST API的问题。他谈到了API的问题,这些问题尚不清楚,如果您获得大量帖子或其他内容的数组,那么查询参数如何使情况复杂化。他还指出,由于GraphQL具有严格的类型系统,因此不会出现此问题。
我认为Kyle所说的是一个组织问题,您需要一个组织解决方案。
当您允许开发人员部署REST API而不发布Open API Specification(OAS)或类似内容时,您会遇到他所描述的那种问题。使用OAS,可以很容易地描述所有资源。OAS还允许您描述每个端点的OAuth2流和所需范围。此外,您可以描述查询参数的确切类型和验证规则,这是GraphQL所缺少的功能。
从GraphQL来看,无法描述身份验证,授权和输入验证。GraphQL缺少这些功能,因为Facebook的发明者在不同的层上解决了这个问题。无需他们将这些功能添加到GraphQL。您可以向架构中添加自定义指令,以实现类似于OAS的结果,但这将是您必须维护的自定义实现。
您可能会认为OAS无法保证API的响应符合规范。你说的没错。但是GraphQL模式如何保证任何内容?
GraphQL自省是将特定的GraphQL查询发送到服务器以获取有关GraphQL模式的信息的操作。GraphQL服务器可以自由选择所需的任何类型。如果您发送查询,则服务器可以使用内省响应中不符合GraphQL模式的响应进行回答。
以Apollo联盟为例。您将架构上载到架构注册表中,然后错误地部署了错误版本的GraphQL服务器。如果更改字段的类型,客户端可能会感到困惑。
当我们谈论GraphQL中的类型安全性时,实际上是指我们相信GraphQL服务器的行为完全符合自省查询响应所通告的行为。为什么我们不能以相同的方式信任Open API规范?我想我们可以。如果我们不这样做,那就是人员问题,而不是技术问题。
更好的客户端性能
下一段简短介绍了GraphQL如何提高客户端性能并减少网络往返次数。
我认为,与重量级的GraphQL客户端相比,我已经充分解释了BFF的功能强大得多,以及从“过时的重新验证模式”中获得了多少收益。
也就是说,GraphQL确实确实减少了请求数量并减少了整体数据传输。但是,您应始终考虑将GraphQL客户端添加到前端的成本。
减少记录和浏览API的时间
下一部分将介绍如何将OAS之类的工具用于RESTful API开发以及在微服务环境中维护多个OAS的挑战。Kyle将单个GraphQL模式与分布在多个git存储库中的Swagger文件进行了比较。
我认为很明显,导航单个GraphQL模式比坐在git存储库中查看多个OAS文件要简单得多。但是,公平地说,我们必须将在一个苹果与另外一个苹果进行比较。如果您想提高开发人员的工作效率,就不会将OAS文件粘贴到git存储库中,而是每天都将其命名。您运行的是一个开发人员门户,您可以在其中搜索API并在它们之间导航。
OAS依赖于JSON-Schema,该功能具有惊人的功能:您可以引用另一个文档中的对象类型。您可以将OAS分为多个文件,如果需要,它们可以互相引用。还有工具可以将多个OAS文件合并到一个OAS文档中。然后,您可以使用此文档,并将其输入到开发人员门户中,该门户可让您整体浏览所有API。请记住,设置所有这些都会产生额外的费用。您需要运行一个开发门户或购买一个。您必须描述所有的API,至少在开始时,这可能是一种负担。
要添加的一件事是,有许多框架可以让您用自己喜欢的编程语言来描述架构,例如通过定义对象或类。然后,您将获得一个自动生成的Open API规范,该规范将在知名端点上提供。
让我们将其与GraphQL进行比较。基本上有两种方法,首先是SDL,然后是代码。无论采用哪种方式,最终都会得到一个GraphQL模式,该模式描述所有类型以及字段,并允许您对其进行注释。
那么,有什么区别呢?OAS带有更多的开销来进行设置。另一方面,OAS具有内置的支持文档记录示例用例,身份验证和授权以及输入验证规则。
请记住,GraphiQL本身没有多个GraphQL模式的概念。如果您具有多个GraphQL(微)服务,则必须运行或购买专用组件,例如,类似于REST API开发人员门户的架构注册表。
我想专门介绍一个额外的段落是API用例。仅仅因为您拥有OAS或GraphQL模式,并不意味着您的API有充分的文档记录。API用户可以使用该API做什么?他们如何使用它?什么是好用例?有什么不好的?在哪里寻求帮助?如何验证用户?我需要API密钥吗?用一种可以帮助API使用者使用API的方式来记录您的API,比在类型和字段中添加描述要多得多。OAS允许您添加示例有效负载并对其进行描述。GraphQL缺少此功能。在Stripe上看到一个积极的例子。它们远远超出了Swagger或GraphQL Playground所能达到的范围。
另一方面,如果您查看GitHub的公共GraphQL API,您将找不到单个示例查询。假设您要获取有关存储库及其所有问题的信息。您必须打开GraphiQL并开始搜索。但是,GraphiQL中的搜索功能并没有真正帮助您。有人需要坐下来写示例查询和有关如何使用API的用例。否则,真的很难上手。
因此,尽管社区一直在说“ GraphQL正在自我记录”,但仅此功能并不能提供有用的API。OAS为您提供了添加用例的工具,但是您仍然必须编写它们。无论您选择哪种工具或语言,都需要努力使API对其他人有用。
传统应用程序的支持
在这一段中,作者说,为移动应用保留旧版本的REST API很痛苦。他的结论是,由于我们仅使用单个GraphQL服务器,因此不会出现此问题。
抱歉,我再次得出完全不同的结论。如果将规则设置为禁止版本控制,则可以添加新端点或交换现有端点的实现。在这种情况下,GraphQL和REST之间没有区别。对于REST和GraphQL API而言,支持旧版应用程序都是一个挑战。您需要找到一种不破坏客户端和服务器之间合同的方法。服务器是否公开REST或GraphQL都无关紧要,问题是相同的。
更好的错误处理
关于错误处理,作者描述了一个场景,即与将用部分数据进行响应的单个GraphQL查询相比,客户端必须进行3个后续REST API调用。
使用GraphQL,解析部分数据的逻辑就在服务器中。客户端需要具有其他逻辑以对部分响应做出适当反应。
借助REST,获取部分数据的逻辑可以位于客户端或BFF中。无论哪种方式,其逻辑或多或少都与GraphQL相同,只是位于其他地方。显然,REST API用例还需要客户端中的逻辑来处理部分响应。这种逻辑几乎与GraphQL用例中的逻辑相同。
没有什么可以阻止您在REST响应中返回有关失败原因的特定信息。OAS允许联合类型,因此您可以自由地向客户提供有关部分响应的丰富信息。这类似于Sascha Solomon(https://sachee.medium.com/200-ok-error-handling-in-graphql-7ec869aec9bc)描述的响应联合的概念。
GraphQL确实具有更好的错误处理能力吗?我认为OAS和GraphQL都为您提供了很好的工具,以非常用户友好的方式处理错误。开发人员应充分利用这些工具。没有免费的午餐。
结论
Kyle在全文中总结说,GraphQL是API的未来,因为它在性能,有效负载大小,开发人员时间和内置文档方面都优越。
我同意GraphQL是API的未来,但出于不同的原因。
更好的性能和更小的有效负载大小不是GraphQL的独特功能。您可以使用其他工具获得更好的结果,或者必须扩展GraphQL,例如使用Relay来获取持久化查询。为了从GraphQL文档中获得真正的好处,您肯定要做的不只是在架构中添加描述。
一旦尘埃落定,炒作就消失了,我们必须看看事实。我们不应该试图让世界相信GraphQL。使用GraphQL有很多优点,但是根据您的用例,您可能不会真正从中受益。与其说GraphQL是圣杯,不如说是更微妙的回应。
解决此问题的最佳方法是先查看问题,然后对解决问题的可能工具进行独特的比较。如果您的组织无法实现REST API,那么GraphQL又能如何解决此问题?也许您组织内的某些事情必须改变?另一方面,如果这不是组织上的问题,并且您完全确定REST不是您的用例的好选择,那么我敢打赌,您一定会喜欢GraphQL。
GraphQL本身几乎没有用。而是GraphQL工具使GraphQL如此强大。是社区,是我们!像Apollo,Hasura,The Guild,FaunaDB,Dgraph,GraphCMS之类的公司,我也希望WunderGraph也如此,它们使GraphQL如此强大。它是GraphiQL,各种GraphQL客户端,模式缝合,联合。整个工具生态系统是GraphQL成为下一件大事的原因。
更多工具和服务将加强生态系统。更强大的生态系统将导致更多的采用,这又将吸引更多的公司为GraphQL生态系统添加服务和工具,这是一个非常积极的循环。
GraphQL在这方面与Kubernetes非常相似。Docker(容器运行时)还不够。将复杂的Syscall封装为易于使用的API是使能因素,但是为了创建一个丰富的生态系统,需要一个调度程序,该调度程序应具有足够的表现力并具有非常容易的扩展性。
GraphQL提供了一种与Docker一样简单的语言来定义和使用API。如果您以前看过几行Javascript和JSON,则GraphQL会立即让您感到熟悉。但是类似于Docker,该语言本身并不强大。它是可扩展性及其周围的工具。
当Kyle问“ Why GraphQL”时,我认为他的实际意思是“ Why Apollo”。答案很简单。没有人愿意围绕REST API构建一个丰富的生态系统。尝试根据开放API规范生成React.JS客户端。与GraphQL客户给您的东西相比,这种体验很烂。没有人想出一种好的商业模式来解决这个问题。输入GraphQL,您将获得大量工具来抽象出您不想处理的问题。
REST API与所描述的用例的相关性将降低,而不是因为GraphQL是高级的。它是使GraphQL继续获得市场份额的工具和生态系统。与REST相比,GraphQL生态系统的扩展速度非常快。
超媒体API在服务器呈现的Web应用程序中一直发挥着巨大作用,并且仍然扮演着重要角色。但是,网络正在向前发展。用户期望从网站获得的原生体验。Jamstack正在接管前端。具有服务器端渲染和动态Javascript客户端的混合模型是这些应用程序的实现者。
RESTful API擅长解决一系列不同的问题。他们不会消失,恰恰相反!对于行业正在转变的这种类型的应用程序,它们并不是正确的工具。我认为REST API是内部API,合作伙伴API和服务器到服务器通信的理想工具。这是GraphQL在REST方面并未真正带来任何好处的领域。与RPC一起,它将在这一领域拥有美好的未来。
版权声明
本文为[解道jdon]所创,转载请带上原文链接,感谢
https://www.jdon.com/55312
边栏推荐
- Aprelu: cross border application, adaptive relu | IEEE tie 2020 for machine fault detection
- The vowels in the inverted string of leetcode
- 链表
- 你有没有想过为什么交易和退款要拆开不同的表
- Introduction to nmon
- A few lines of code can easily transfer traceid across systems, so you don't have to worry about losing the log!
- 计算机网络 应用层
- VIM Introduction Manual, (vs Code)
- 写时复制集合 —— CopyOnWriteArrayList
- The road of cloud computing - going to sea - small goal: Hello world from. Net 5.0 on AWS
猜你喜欢
非阻塞的无界线程安全队列 —— ConcurrentLinkedQueue
Introduction to nmon
1.操作系统是干什么的?
云计算之路-出海记-小目标:Hello World from .NET 5.0 on AWS
Mobile big data own website precise marketing and accurate customer acquisition
基于链表的有界阻塞队列 —— LinkedBlockingQueue
AQS 都看完了,Condition 原理可不能少!
架构中台图
14.Kubenetes简介
上线1周,B.Protocal已有7000ETH资产!
随机推荐
代码保存
国内三大云数据库测试对比
作业2020.11.7-8
VIM Introduction Manual, (vs Code)
梁老师小课堂|谈谈模板方法模式
简单介绍c#通过代码开启或关闭防火墙示例
How to deploy pytorch lightning model to production
大数据岗位基础要求有哪些?
链表
AQS 都看完了,Condition 原理可不能少!
SAP S/4HANA 2020安装实录
Octave基本语法
Several common playing methods of sub database and sub table and how to solve the problem of cross database query
Decorator (2)
When iperf is installed under centos7, the solution of make: * no targets specified and no makefile found. Stop
Python的特性与搭建环境
centos7下安装iperf时出现 make: *** No targets specified and no makefile found. Stop.的解决方案
实现图片的复制
What are the basic requirements for big data posts?
装饰器(一)