GraphQL和微服务架构

Fab*_*lio 145 architecture microservices graphql

我试图了解GraphQL最适合在微服务架构中使用的位置.

关于只有1个GraphQL架构作为API网关代理对目标微服务的请求并强制其响应存在争议.微服务仍然会使用REST/Thrift协议进行通信思考.

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

第一种方法

将1个GraphQL架构作为API网关将有一个缺点,每次更改微服务合同输入/输出时,我们必须在API网关侧相应地更改GraphQL架构.

第二种方法

如果每个微服务使用多个GraphQL模式,那么在某种程度上是有意义的,因为GraphQL强制执行模式定义,并且消费者需要尊重微服务给出的输入/输出.

问题

  • 在哪里可以找到适合设计微服务架构的GraphQL?

  • 您将如何使用可能的GraphQL实现设计API网关?

hel*_*fer 212

绝对接近#1.

让您的客户与多个GraphQL服务进行通信(如方法#2),首先完全违背了使用GraphQL的目的,即提供整个应用程序数据的模式,以允许在单个往返中获取它.

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

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

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

  • @Fabrizio GraphQL的优点在于即使后端REST API发生变化,只要有一种方法可以获得REST服务以前暴露的数据,GraphQL模式仍然可以保持不变.如果它公开了更多数据,那么处理这个问题的规范方法就是将新字段/类型添加到现有模式中.Facebook创建GraphQL的人告诉我他们从未在四年内对他们的架构进行过彻底的改变.他们所做的所有更改都是附加的,这意味着新客户可以使用新功能,而旧客户则可以继续使用. (10认同)
  • 对!:)感谢写这个!我正在通过apollo repos在Medium和github上关注你!您的文章和帖子非常有价值!:) 保持良好的工作!我也认为有一个主题为GraphQL + Microservices的中篇文章会非常有趣! (4认同)
  • +1我应该在我的帖子上放置一个免责声明,我没有使用GraphQL的经验,而是根据在研究过程中非常简短的阅读回答问题.我认为这个答案更能解决OP的问题. (3认同)
  • @helfer:这真的很有意义:)谢谢.在这个华丽的答案之上我几乎没有问题. - 你是说GraphQL必须用作API网关? - 假设我有一个**订单**微服务,它暴露了一个REST或GraphQL端点.一旦我完成它,我必须更新主要的GraphQL架构,以反映微服务将公开的完全相同的数据?这听起来不是重复或远离应该独立部署的微服务文化吗?对微服务的任何更改都必须反映/复制到Main GraphQL Schema? (2认同)

Ena*_*yat 28

请参阅此处的文章,该文章说明方法#1如何以及为何更好地运作.另请参阅我提到的文章中的下图: 在此输入图像描述

将所有内容置于单个端点后面的主要好处之一是,与每个请求都有自己的服务相比,可以更有效地路由数据.虽然这是GraphQL经常被吹捧的价值,复杂性和服务蠕变的减少,但由此产生的数据结构也可以非常明确地定义数据所有权,并明确界定.

采用GraphQL的另一个好处是,您可以从根本上断言对数据加载过程的更大控制.由于数据加载器的过程进入其自己的端点,因此您可以部分地,完全地或通过警告来满足请求,从而以极其精细的方式控制数据的传输方式.

以下文章非常好地解释了这两个好处:https://nordicapis.com/7-unique-benefits-of-using-graphql-in-microservices/


Vic*_*nez 8

我一直在使用 GraphQL 和微服务

根据我的经验,对我有用的是两种方法的组合,具体取决于功能/用途,我永远不会像方法 1 那样拥有单个网关,但也不会像方法 2 那样为每个微服务提供 GraphQL。

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

在此输入图像描述

  • 应用程序(产品、购物篮、运输、库存、需要/链接到其他服务)

  • 支付

  • 用户

这样,您需要额外注意从依赖服务公开的所需/链接的最小数据的设计,例如身份验证令牌、用户 ID、付款 ID、付款状态

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

这种方式比较容易...

  • 根据不同的网关节点的使用情况缩放/关闭它们。(例如,人们可能并不总是编辑他们的个人资料或付款......但搜索产品可能会更频繁地使用)。

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

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

更新:

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

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

更新2:

只是添加功能分离的另一个示例,我将与管理文件、上传、创建、删除、将文件分组到存储桶、批量删除、私有文件、cors 配置等相关的功能分离到一个图表中......而其他图表/服务只需要一些详细信息,例如预签名帖子或生成的 url/fileid


HFX*_*HFX 7

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

有一些很好的工具可以将模式组合成一个,例如graphql-weaver和apollo的graphql-tools,我正在使用graphql-weaver它,它易于使用且效果很好.


van*_*ome 5

截至2019年中,第一种方法的解决方案现在由阿波罗人创造(以前通常称为GraphQL拼接),名称为“ Schema Federation ” 。他们还提出了模块及这一点。@apollo/federation@apollo/gateway

添加:请注意,使用Schema Federation,您不能在网关级别修改架构。因此,对于架构中需要的每一点,都需要有一个单独的服务。