何时以及如何在微服务架构中使用GraphQL

我试图理解GraphQL在微服务架构中最适合使用的地方。

对于只有一个GraphQL模式作为API网关代理请求到目标微服务并强制它们的响应,存在一些争论。微服务仍然使用REST / Thrift协议进行通信。

另一种方法是使用多个GraphQL模式,每个微服务一个。使用一个较小的API Gateway服务器,将请求路由到目标微服务,并将请求的所有信息+ GraphQL查询。

1号的方法

使用一个GraphQL模式作为API网关会有一个缺点,每次你改变你的微服务契约输入/输出时,我们必须在API网关端相应地改变GraphQL模式。

2方法

如果每个微服务都使用多个GraphQL模式,在某种程度上是有意义的,因为GraphQL强制了一个模式定义,消费者需要尊重微服务给出的输入/输出。

问题

  • 你在哪里发现GraphQL适合设计微服务架构?

  • 你会如何设计一个API网关与一个可能的GraphQL实现?

60818 次浏览

绝对接近第一条。

让您的客户端与多个GraphQL服务通信(如方法#2所示)完全违背了使用GraphQL的初衷,GraphQL的目的是在您的整个应用程序数据上提供一个模式,以允许在一次往返中获取它。

从微服务的角度来看,使用无共享架构似乎是合理的,但对于客户端代码来说,这绝对是一场噩梦,因为每次你改变一个微服务时,你都必须更新客户端的所有。你一定会后悔的。

GraphQL和微服务是完美的组合,因为GraphQL对客户端隐藏了你拥有微服务架构的事实。从后端角度来看,您希望将所有内容都分割为微服务,但从前端角度来看,您希望所有数据都来自单个API。使用GraphQL是我所知道的能让你同时做到这两点的最好方法。它允许你将后端拆分为微服务,同时仍然为所有应用程序提供一个API,并允许连接来自不同服务的数据。

如果你不想为你的微服务使用REST,你当然可以让每个微服务都有自己的GraphQL API,但你仍然应该有一个API网关。人们使用API网关的原因是为了使从客户端应用程序调用微服务更易于管理,而不是因为它很适合微服务模式。

对于方法#2,实际上这是我选择的方式,因为它比手动维护烦人的API网关容易得多。通过这种方式,您可以独立地开发服务。让生活更轻松:P

有一些很棒的工具可以将模式组合成一个,例如graphql-weaver和apollo的graphql-tools,我使用的是graphql-weaver,它很容易使用,工作效果很好。

这篇文章建议方法#1。下面这张图片也摘自上述文章: enter image description here < / p >

将所有内容都放在单个端点后的主要好处之一是,可以比每个请求都有自己的服务更有效地路由数据。虽然这是GraphQL经常被吹捧的价值,减少了复杂性和服务蔓延,但由此产生的数据结构还允许对数据所有权进行非常好的定义和清晰的描述。

采用GraphQL的另一个好处是,您可以从根本上对数据加载过程进行更大的控制。因为数据加载器的过程进入自己的端点,所以您可以部分地、完全地或带有警告地满足请求,从而以极其细粒度的方式控制数据传输方式。

下面的文章很好地解释了这两个好处

截至2019年年中,1号的方法的解决方案现在有了“模式联合会阿波罗人创造的(以前这通常被称为GraphQL拼接)。 他们还为此提出了模块@apollo/federation@apollo/gateway

ADD:请注意,使用模式联合,您不能在网关级别修改模式。因此,对于模式中需要的每一个比特,都需要有一个单独的服务。

我一直在使用GraphQL和微服务

根据我的经验,对我来说有效的是根据功能/用法将两种方法结合起来,我永远不会像方法1那样只有一个网关,但也不会像方法2那样为每个微服务使用GraphQL。

例如,根据Enayat的答案图像,在这种情况下,我要做的是有3个图网关(而不是图像中的5个)

enter image description here

  • 应用程序(产品,篮子,航运,库存,需要/链接到其他服务)

  • < p >付款

  • < p >用户

通过这种方式,您需要特别注意从依赖的服务中公开的所需/链接的最小数据的设计,如认证令牌、用户id、paymentid、支付状态

以我的经验为例,我有“用户”;网关,在那个GraphQL我有用户查询/突变,登录,登录,退出,更改密码,恢复电子邮件,确认电子邮件,删除帐户,编辑个人资料,上传图片等…这张图本身就相当大!,它是分开的,因为在最后,其他服务/网关只关心结果信息,如用户id,名称或令牌。

这样更容易……

  • 扩展/关闭不同网关节点,取决于它们的使用情况。(例如,人们可能并不总是在编辑他们的个人资料或支付…但搜索产品可能使用得更频繁)。

  • 一旦网关成熟,增长,使用是已知的,或者您对该领域有了更多的专业知识,您可以确定模式的哪些部分可以拥有自己的网关(…发生在我身上的一个与git存储库交互的巨大模式,我分离了与存储库交互的网关,我看到唯一需要的输入/链接信息是…文件夹路径和预期的分支)

  • 存储库的历史更加清晰,您可以有一个存储库/开发人员/团队专门用于网关及其涉及的微服务。

更新:

我有一个在线的kubernetes集群,它使用与我在这里描述的相同的方法,所有后端都使用GraphQL,都是开源的,这里是主存储库: https://github.com/vicjicaman/microservice-realm < / p >

这是对我的答案的更新,因为我认为如果答案/方法是正在运行的备份代码,并且可以参考/审查,那就更好了,我希望这能有所帮助。

更新2:

只是添加了另一个功能分离的例子,我将与管理文件、上传、创建、删除、将文件分组到桶、批量删除、私有文件、cors配置等相关的功能分离到一个图表中……而其他图形/服务只需要一些细节,如预先签名的帖子或结果url/fileid

截至2019年,最好的方法是编写实现< >强阿波罗网关< / >强规范的微服务,然后使用网关以下方法#1将这些服务粘合在一起。 构建网关的最快方法是像这一个这样的docker映像 然后使用docker-compose命令并发启动所有服务:

version: '3'


services:
service1:
build: service1
service2:
build: service2
gateway:
ports:
- 80:80
image: xmorse/apollo-federation-gateway
environment:
- CACHE_MAX_AGE=5
- "FORWARD_HEADERS=Authorization, X-Custom-Header" # default is Authorization, pass '' to reset
- URL_0=http://service1
- URL_1=http://service2

从这个问题中描述的方式来看,我相信使用自定义API网关作为编排服务对于以企业为中心的复杂应用程序非常有意义。GraphQL可以是该编排服务的一个不错的技术选择,至少在查询方面是这样。第一种方法(所有微服务都采用一种模式)的优点是能够将来自多个微服务的数据拼接在一个请求中。这可能很重要,也可能不重要,这取决于你的情况。如果GUI同时调用来自多个微服务的呈现数据,那么这种方法可以简化客户端代码,这样一次调用就可以返回适合与Angular或React等框架的GUI元素绑定的数据。这种优势不适用于突变。

缺点是数据api和业务流程服务之间的紧密耦合。发布不再是原子的。如果您避免在数据api中引入向后的破坏性更改,那么只有在回滚版本时才会引入复杂性。例如,如果您即将发布两个数据api的新版本,并在编排服务中进行相应的更改,并且您需要回滚其中一个版本,而不需要回滚另一个版本,那么您将被迫回滚所有三个版本。

GraphQL vs REST的比较中,你会发现GraphQL没有RESTful api那么高效,所以我不建议用GraphQL代替REST来使用数据api。

对于问题1,Intuit在几年前宣布迁移到One Intuit API生态系统(https://www.slideshare.net/IntuitDeveloper/building-the-next-generation-of-quickbooks-app-integrations-quickbooks-connect-2017)时承认了GraphQL的力量。Intuit选择了方法1。您提到的缺点实际上阻止了开发人员引入可能破坏客户端应用程序的破坏性模式更改。

GraphQL在许多方面帮助提高了开发人员的工作效率。

  1. 当为一个领域设计一个新的微服务时,工程师(后端/前端/涉众)就领域实体的模式达成一致。一旦模式被批准,它就会与主域模式(通用)合并,并部署在Gateway上。前端工程师可以开始使用此模式编写客户端应用程序,而后端工程师则实现该功能。拥有一个通用模式意味着没有两个具有冗余功能的微服务。
  2. GraphQL帮助客户端应用程序变得更简单、更快。想要从多个微服务中检索数据/更新数据?所有客户端应用程序需要做的是触发一个GraphQL请求,API网关抽象层将从多个源(微服务)获取和整理数据。像Apollo这样的开源框架(https://www.apollographql.com/)加快了GraphQL采用的步伐。

  3. 随着移动设备成为现代应用程序的首选,从零起点设计较低的数据带宽需求非常重要。GraphQL通过允许客户端应用程序只请求特定的字段来提供帮助。

问题2:我们在API Gateway上构建了一个自定义抽象层,它知道模式的哪一部分属于哪个服务(提供者)。当查询请求到达时,抽象层将请求转发给适当的服务。一旦基础服务返回响应,抽象层就负责返回所请求的字段。

然而,现在有几个平台(Apollo服务器、GraphQL -yoga等)允许人们在短时间内构建一个GraphQL抽象层。

在使用graphql引导微服务生态系统时,我们也有类似的担忧。我们可以用Apollo GraphQL解决这个问题。

我们为One Platform从头构建了这些解决方案。以服务结尾的文件夹是微服务,其他的是spa(单页应用程序)

它由各种微服务和带有API网关的spa组成,API网关是多个微服务的主要接口。

与此同时,你可以找到一个OP命令行生成器,它可以帮助你从零开始引导微服务。

项目- https://github.com/1-Platform/one-platform

我请求请看看这个项目,并随时采取,如果这看起来对你很好。

问候

Rigin Oommen