概述
微服务是一种体系结构样式,其中对特定业务领域,复杂应用程序的分析和建模被分解为一组小型且特定的,具有低耦合度的服务。每个微服务都是一个小型,独立且可部署的应用程序。 微服务体系结构的概念类似于分离前端和后端的概念。前端应用程序控制其自己的所有UI级别逻辑,而业务逻辑是通过对相关微服务的API调用来完成的。随着前端单页应用程序框架的不断增长以及移动应用程序的普及,无论是移动本机开发还是混合应用程序开发,因此前端和后端分离使Web和移动应用程序成为客户端。客户端只需要通过API查询和修改资源。 下图显示了不存在BFF和在前端和后端添加BFF之间的主要区别。
1.传统的前端和后端分离应用
在传统的前端和后端设计中,通常移动应用程序或网站直接访问后端服务,后端微服务相互调用,然后将最终结果返回给前端客户端。对于客户端(尤其是移动客户端)而言,太多的HTTP请求非常昂贵。因此,为了最小化请求的数量,前端通常倾向于通过单个API获得关联的数据。这意味着有时后端将执行一些与UI相关的逻辑处理,以满足客户端的需求。
2. BFF的前端和后端架构
BFF的前端和后端体系结构的最大区别是,前端(移动,Web)不再直接访问后端微服务,而是通过BFF层对其进行访问。和每一个客户都会有一个BFF服务。使用BFF,微服务之间的相互调用较少。这是因为某些UI逻辑是在BFF级别处理的。
2.1 BFF和API网关
从对BFF的上述理解来看,由于BFF是前端和后端访问的中间层服务,因此BFF和API网关有什么区别?首先让我们看一下API网关的常见实现。(可以通过多种方式设计API网关。这里仅是三个示例。)
2.1.1 API网关为所有客户端提供相同的API
例如:/api/accounts。在这种情况下,API Gateway不会区分客户端类型,如下所示:
2.1.2 API网关为每个客户端提供单独的API
例如:/services/mobile/api/accounts和/services/web/api/accounts。API网关 基于不同的API确定来自哪个客户端,然后分别处理它们以返回不同客户端所需的资源。
2.1.3 多个API网关为每个客户端提供单独的API
实际上,BFF类似于API网关的这种实现模式。
2.2 GraphQL和REST
GraphQL是API的查询语言,是用于使用现有数据来完成这些查询的运行时。GraphQL为您的API中的数据提供了完整且易于理解的描述,使客户能够准确地询问他们所需的内容,仅此而已,使随着时间的推移更容易开发API并启用强大的开发人员工具。
GraphQL和REST之间有何异同?我们可以通过以下示例了解它: REST可以通过以下方式访问:
Request:
GET http://127.0.0.1/api/accounts
Response:
[
{
"id": 88,
"name": "Mena Meseha",
"photo": "http://bucket.s3.amazonaws.com/photo.jpg"
},
...
]
对于使用GraphQL访问的相同请求,过程如下:
Request:
POST http://127.0.0.1/graphql
Body:
query {accounts { id, name, photo } }
Response:
{
"data": {
"accounts": [
{
"id": 88,
"name": "Mena Meseha",
"photo": "http://bucket.s3.amazonaws.com/photo.jpg"
},
...
]
}
}
与REST风格相比,GraphQL具有以下功能:
2.2.1 按需数据模型定义
例如,对于上述/accounts访问,如果客户端仅对account.id和感兴趣account.name。因此客户只需要传递account {id \n name}给即可query。该模型在后台定义。客户端仅需要获取其关心的数据。
2.2.2 在一个请求中获取许多资源
例如,您可能需要获取account.friends和account.friends.address,事实上,这个查询需要从3个不同的资源,这是数据account,friends和address。在REST模式下,可能需要将帐户数据再次发送到另一个API,以获取朋友和地址信息。GraphQL可以查询嵌套的数据级别,因此它极大地减少了客户端请求的数量,并允许客户端通过单个API获得所有所需的数据,如下所示:
{
account(id:88) { // 1st Level
name,
friends { // 2nd Level
name,
address { // 3rd Level
country,
city
}
}
}
}
2.3 GraphQL与REST比较
为了比较GraphQL和REST,主要存在以下差异:
- 1.数据采集: REST缺乏可伸缩性,并且可以按需访问GraphQL。调用GraphQL API时可以扩展有效负载。
- 2.API调用:每种资源的REST操作都是一个端点,而GraphQL只需要一个端点,但是发布主体并不相同。
- 3.复杂数据请求: REST需要对嵌套的复杂数据进行多次调用,而GraphQL调用一次,从而减少了网络开销。
- 4.错误代码处理: REST可以准确地返回HTTP错误代码,GraphQL统一返回200,并包装错误信息。
- 5.版本号: REST是通过v1 / v2实现的,而GraphQL是通过Schema扩展实现的。
2.4 微服务+ GraphQL + BFF实践
我建议使用express-graphql构建项目的BFF端,然后通过Docker进行部署,并且在BFF和微服务后端之间,通过Consul进行服务注册和发现。
3. GraphQL + BFF实践
通过以下方面,您可以考虑基于GraphQL的BFF的一些更好的质量:
3.1 GraphQL和BFF专注于业务点
从业务的角度来看,物业经理(PM App)与息息相关property,因为物业经理管理着一组房屋,因此有必要了解所有房屋概况,并且对于每个房屋都需要知道是否有房屋。相应的维护应用程序。因此,定义了PM App BFF数据结构,maintemamceRequests是property子属性。 对于类似的数据,房屋维护供应商(供应商应用程序)关注维护请求(维护工作订单),因此在供应商应用程序获得的数据中,我们的主体为maintenanceRequest。 因此,因为存在不同的使用方案,所以不同的客户端对同一数据有不同的关注。从这个角度来看,BFF中定义的数据结构才是客户真正关心的。BFF为客户而生,是客户的一部分。应当注意,“业务重点”并不意味着BFF将处理所有业务逻辑。微服务仍应处理业务逻辑。BFF关注客户的需求。
3.2 GraphQL支持版本控制
假设BFF结束已发布到生产环境中。现在我们需要将图(1)的结构更改为图(2)的结构,但是为了不影响旧用户的API访问,此时我们的BFF API必须兼容。如果是REST,我们可能会更新API版本。但是在BFF中,我们可以使用图(3)的结构实现前向兼容性。此时,旧的APP使用黄色区域的数据结构,而新的APP使用蓝色区域定义的结构。
结论
在微服务下基于GraphQL构建BFF并非灵丹妙药。它不一定适合所有项目。例如,使用GraphQL之后,您可能不得不面对多个查询性能问题,但这并不能阻止它成为一个很好的尝试。您确实看到Facebook已经使用了GraphQL,并且Github还打开了GraphQL的API。本文仅是对该想法的介绍。我希望在社区中更多地分享BFF的使用。