跳转到主要内容
Chinese, Simplified

从设计上讲,api是紧密相连的。为了有效地运行和实现创建它们的目的,api被精心设计成可以方便地连接到其他服务,包括内部和外部服务。虽然从用户的角度来看这当然是有益的,但是开发人员经常发现这种开发的结果有一些问题元素。

这些元素的主要特点是,当微服务变得越来越多时,它们就变得更加相互依赖。引入生态系统的每个新微服务都有自己的通信和工作方法,并且必须专门设计为与其他依赖服务交互。

可以采用一些策略来否定微服务架构设计这一方面的许多缺点。一种方法是为前端(BFF)shim创建一个后端,以帮助组织微服务体系结构,并在一个多样化的、广泛的系统中协调功能。

今天,我们将准确地定义前端shim的后端是什么,以及它是如何工作的。我们将重点介绍一些开发时要记住的最佳实践,并讨论一些必须小心避免的潜在失败点。

什么是前端后端?

api本质上是大量的部分,它们朝着一个目标协同工作。但是API设计器通常会创建一些系统,随着时间的推移,这些系统会暴露出一些漏洞或弱点,这些漏洞或弱点需要一小段代码来按照应有的方式对齐所有内容。Phil Calçado描述的前端设计模式的后端是指为每个用户体验开发利基后端的概念。

前端的后端是一种独特的填充类型,它填补了API过程中固有的设计空白。简单地说,BFF是用户体验和它调用的资源之间的一层。当移动用户请求数据时,在BFF情况下,他们的请求通过BFF转换为其下面的一般层。这在功能上意味着什么,可以在下面的例子中演示。

三维打印:经典方法

假设你有一家3D打印公司,可以按需接受订单和打印材料。在传统设计中,您将看到以下API流:

这种架构有几种用户类型,每种类型都有不同的用户体验和API需求。移动用户使用一个应用程序,桌面用户使用一个web客户端,内部订单由呼叫支持的客户下达,支持人员使用内部程序将订单手动添加到队列中。

从功能上讲,这是通过将每个功能分离成一个应用程序或web服务来实现的,每个应用程序或web服务都调用一个通用API。通用API有每个对象的实例和每个服务所需的调用,并用所需的数据响应特定的调用类型(通过源条目表示)。

虽然这当然是有用的,但它有一些严重的问题。当然,最重要的是所调用的订购API的巨大规模。订购API不仅必须包含桌面和内部解决方案的所有进程,而且还必须使用自己的特定呼叫功能、安全系统和媒体功能处理来自移动应用程序的每个呼叫。

这并不是说,调用的组合必然是问题所在——问题具体在于如何处理这些调用的性质。一个单一的、大的API导航每个调用并调用同一个单一的API是有问题的,而且速度很慢。数据需要以移动解决方案的特定格式和语言呈现,移动解决方案与桌面解决方案完全分离,导致多个重复的功能,并稍微修改了“调整”。

另一个大问题是,一个单一的团队将负责三个不同用户的用户体验,每个用户都有自己的特定需求和体验。像这样把所有的东西聚集在一起是很混乱的,有一个臃肿的内部团队的效果。

三维打印:微服务设计

我们可以通过以下流程变化来解决其中的许多问题:

在这种设计中,每个应用程序客户机类型都有自己的专用API,有效地生成了一系列专门针对每个用户体验的微服务,这与第一个示例不同,后者依赖于通用API。在这种情况下,每个调用都是通过一个特定的、独立的API进行推送的,然后在后端利用资源。到目前为止还不错,对吧?不是那么快。虽然许多问题已经解决,但出现了一个全新的问题体系。

这里最大的问题是微服务的连续性。虽然我们已经根据用户的使用体验以有意义的方式将许多功能分离出来,但是我们有三个不同的api调用相同的后端功能,这意味着代码和功能有很多重复。最重要的是,随着API的更新和发展,这将意味着在团队经济和时间成本以及API的大小和速度方面都会有更大的开销。

我们把一个极端的世界换成了另一个极端的世界。在许多方面,这是大多数提供者当前的API环境。因此,人们采用了各种各样的策略。其中一个,也是我们今天讨论的,是前端shim后端的想法。

三维打印:前端后端

我们在概念上所说的是一个“翻译”层,一个接受不同调用并允许它转换为公共形式的填充程序。当我们在这个例子中添加很多概念层时,请记住“垫片”是相当小的代码片段,比整个API小得多。

虽然这种设计看起来像是microservices体系结构的一个碳拷贝重塑,但实际上您在这里看到的是一层翻译服务。每个shim由一个“shim团队”与另一个保持一致,而订购API由一个API团队管理。这难道不应该和我们之前看到的问题一样吗?

这里的关键区别在于电话的处理。在上面的“通用API”设计中,我们有一个单独的API,其中包含由源标识触发的初始数据集的变体。问题是每个源都必须有自己的专业调用,并且数据在传递之前必须由API操作。

在microservices解决方案中,我们通过为每个服务提供单独的api来解决这个问题,但是问题仍然存在,表现为缺乏连续性,以及随之而来的团队范围和规模的不断扩大。

在shim方法中,我们得到的是一组不同的调用被转换成一个调用。不同的数据类型转换和系统是在从API到shim的数据处理过程中完成的,基本上是将特定于服务的调用转换为一般调用*。

这不仅缓解了通用API和开发它们的团队的代码库大小和范围问题,而且还将处理能力和责任转移到可以由单个shim团队设计和维护的多个服务上。

我们实际上是在建造一条高速公路,避免所有的地面和收费公路——这意味着更好、更高效的吞吐量。

最佳做法

考虑到所有这些,让我们讨论在开发此类系统时要避免的一些最佳实践和一般陷阱。

避免垫片到API的转换

开发人员可能遇到的最大陷阱之一是,用与微服务相同的方式来考虑填充程序。这两件事是完全不同的,需要这样编码。

当我们谈论一个转换填充时,我们真正谈论的是“当这个数据被返回时,把它从这个类型的数据转换成应用程序指定的数据类型。”我们谈论的不是一个自包含的、包罗万象的API,而是一个转换层。

垫片复制

创建填充程序的整个目的是为了提高代码库的效率并消除重复,因此这是一个值得注意的陷阱,这看起来很奇怪。然而,实际情况是,那些新开发shim的人可能会认为shim对于每个独特的用户体验都是必需的。但是你应该是多大的颗粒呢?

这里缺少的一点是,每个用户体验应该按体验类型分组,而不是按体验的来源分组。例如,开发人员可能希望为iOS、Android、Windows Mobile和第三方移动操作系统开发单独的垫片,认为这样可以获得更好的性能。

事实上,大多数移动体验都可以接受某些常见的数据类型,因为用户体验非常相似。操作系统之间的应用程序体验非常相似,不足以保证它们各自的垫片。

过度依赖垫片

与Shim-to-API转换的思想相关,存在着Shim成为过多拐杖的明确威胁。虽然使用shim概念作为安全性、扩展功能等方面的前线是非常诱人的,但是shim只是一个shim,它不只是一个转换层。

因此,尽量避免过度依赖垫片。主要的API代码库仍然应该处理所有的功能,并且仍然应该做一个正确的API应该做的所有事情-填充程序应该填补空白,而不是添加功能和服务。

提供要求的内容

作为BFF/shim开发概念的一部分,每个体验只需要特定的数据项。开发人员可能会认为shim是一个过滤器和一个转换器,但这不是我们想要的——API应该只提供shim请求的数据。

想象一下,一个对商品进行分类并将其与生产日期、类型、购买频率等数据进行核对的购物区。移动应用程序可能只需要每个条目中包含的50个数据对象中的10个,而桌面应用程序将需要其中的40个,而内部应用程序将需要全部50个。

很容易让shim本身在传输过程中去掉不需要的数据,但这开始促使它成为一个功能性API而不是shim。这种类型的数据处理应该使用源触发器在API级别本身上完成。每个填充程序都应该通知API客户端类型,API应该只响应对特定数据集的请求,而不是提供整个数据对象。

这是作为初始代码基对象的一种方法来完成的,应该用垫片的概念和不同的用户体验来分隔这些对象。这样做将提高整体速度,减少带宽,并提高体验满意度。

结论

在所有这些过程中,重要的是要记住,shim只是解决几乎通用的架构问题的一种方法。虽然确实有其他策略,但当面对复杂的后端和广泛变化的用户体验时,shim非常有效。总结一下我们讨论过的架构类型:

在经典的设计中,我们有一个移动电话、一个桌面电话和一个内部电话。所有这三个调用都需要自己的条目或至少一个代码集来处理通用API中的转换。

在微服务设计中,我们有一个移动电话、一个桌面电话和一个内部电话。这些调用分别与它们自己的API、移动API、桌面API和内部API交互。

在BFF垫片设计中。我们有移动电话、桌面电话和内部电话。这些调用都被mobile shim、desktop shim和internal shim截获。shim将单个调用转换为一般调用,然后由调用shim返回并翻译,调用shim就是发出请求的shim。

它是否能够正确实现取决于每个服务的特定用例、后端架构和业务方法。这就是说,一个BFF在被使用的时候是非常强大的——它是不同API服务和体验之间的一个转换层。

 

原文:https://nordicapis.com/building-a-backend-for-frontend-shim-for-your-microservices/

本文:

讨论:请加入知识星球【首席架构师圈】或者加小号【jiagoushi_pro】

Tags
 
Article
知识星球
 
微信公众号
 
视频号