最近,我参与了一个从头开始构建新应用程序的项目,该项目是一个拥有许多前端用户的大型企业级业务应用程序。为了实现所需的逻辑和功能,该项目的架构设计中需要构建大约 50 个微服务,其中一些微服务需要原生地部署到云上,而另一些则需要托管在本地的 OpenShift 集群中,且 OpenShift 集群将成为与遗留数据系统的连接纽带。
由于这家公司之前从未构建过这么多微服务,也从未涉足过云计算领域,所以遇到的很大挑战就是如何编排服务网格,以确保对前端的更改不会破坏应用程序,对后端服务的更改也不会破坏前端。
我推荐的解决方案是:将 GraphQL 用作企业 API 网关。
简化部署编排
几乎所有 API 都存在这样一个问题:如果对其中一个 API 做了更改,那么很可能会导致另一个 API 崩溃。虽然“微服务”的存在本身就是解决这个问题,但在实际应用中也会发生响应时缺少数据的情况。
如果同时部署了不同服务的平台,情况会变得更加复杂。这时,我们往往会使用不同的 CI/CD 管道来实现本地 OpenShift 与云原生 Lambda 服务。
而使用 GraphQL 则相当于为所有服务都提供了前端,简化了将编排部署到平台的步骤。前端应用程序只会和一个端点通信,而这个端点是用于查询和发布数据的无版本模式,因此,当后端发生了更改时,不需要对前端进行更改。GraphQL 端点保持不变,即使后端发生变化,它也可以继续运行。
Lambda 的 CI/CD 管道示例
简化安全性
这个架构的另一个挑战就是如何保护所有的服务?我们是否构建了一个在使用其他服务之前必须先确定其安全性的安全令牌服务?我们是否为每个服务添加了逻辑以确保令牌在头文件中、在任何地方都经过了验证?
如果要我来回答以上问题,那么我的答案是否定的。而使用 API 网关来管理所有的服务,可以将安全检查 / 验证向上移一层,开发人员可以专注于开发中具有业务价值的功能,同时还减少了到处重复的膨胀和冗余代码。
为了提高安全性,我们可以使用 GraphQL 实现以下几点:
深度限制
速率限制
使用 GraphQL 速率限制(GraphQL Rate Limit)插件,我们可以通过三种不同方式(自定义指令 graphql-shield、或者基本速率限制函数)为查询和突变指定限制。
该插件允许我们设置时间窗口和限制,针对高度易受攻击的突变和查询(如登录),可以设置一个较大的时间窗口,而针对较不易受攻击的查询,可以设置更短的限制。这种方式可以为合法用户提供良好的体验,对攻击者来说则是一个噩梦。
查询成本限制
新的部署选项
如果没有 GraphQL,我们就不得不十分小心的对 API 进行发版和更新。如果运行多个版本的 API,例如 /v1 和 /v2,我们就必须确保上游 API 和前端应用程序对 /v2 进行了更新才能退出 /v1。另外,还必须要在同一代码库或容器中同时支持这两个版本,这使得整个架构变得更加脆弱了,也容易受到重大变更的影响。
而使用 GraphQL 服务作为代理,就可以推出一个 /v2 容器,同时运行这两个版本的容器。我们可以对 GraphQL 解析器进行变更,使其指向 /v2,而无需变更前端代码。
这种方式使得新功能的部署变得更容易了,还可以为任何服务选择任何部署策略,例如:
蓝 / 绿部署(Blue/Green)
金丝雀发布(Canary Release)
功能标记(Feature Flagging)
总结
目前,开发新的应用程序的首选架构是微服务模式,拆分的所有小型服务一起工作,并通过 API 网关暴露出来,以便前端 SPA 应用程序可以使用它们向最终用户呈现信息。而 GraphQL 可以减少攻击面,简化应用程序的开发以及服务的实际部署。
原文链接:
https://levelup.gitconnected.com/graphql-is-the-new-api-gateway-383edeed4bcd
评论 1 条评论