译者按
译者在学习BFF时,有幸读到了作者古川陽介写的这一系列文章,收获颇多。由于在网上没有找到类似的中文资料,所以想将其翻译为中文,分享给小伙伴们。
前言
在本系列“微服务/API时代的前端开发”中,我们将介绍当前备受关注的BFF(Backends For Frontends)。这一篇,我们将主要介绍BFF的概要和例子,作为“超入门”。第2部分将介绍如何创建BFF,第3部分将介绍由前端开发人员使用BFF创建微服务/API的过程。
目标读者是那些Web应用开发经验的人、前端开发人员、以及那些正在构建微服务的人。
什么是BFF(Backends For Frontends)?
顾名思义,它是前端的后端(服务器)。专门为前端而调用API,或者生成 HTML 的服务器。看到这里你可能会想,“这与传统的Web应用服务器有什么不同?”。本质上是一样的,只是专门为前端打造这一点不同而已。
首先,Web应用服务器有如下几种用途:
- 从数据库和全文搜索引擎等中间件获取和更新数据
- 创建一个页面
- 作为HTTP接口从用户那里获取输入信息
在这里,从数据库和全文搜索引擎中获取和更新数据的部分旨在进行管理,同时确保数据的完整性和可靠性。构建页面的部分和获取用户输入信息的部分对应于用户界面(UI),目的是提升用户体验(UX)。
前者作为后端(Backends),而后者作为前端(Frontends),通过前后端的划分让开发者专注于各自的专业领域,这样的架构设计被称为“BFF”。
轮廓图如下所示
graph LR
Browser --> ReverseProxy[Reverse Proxy] --> BackendsForFrontends[Backends For Frontends] --> UserAPI[User API]
BackendsForFrontends --> DiaryAPI[Diary API]
BackendsForFrontends --> ImageAPI[Image API]
像这样,BFF往往采取“设置在反向代理和后端API服务器之间”的配置。反向代理是一个用来替代Web应用服务器,进行静态文件压缩和缓存的服务器。后端API服务器主要与数据库、全文搜索引擎等中间件配合,起到操作资源和管理数据的作用。
BFF负责UI/UX相关的功能,比如在这两个服务器之间建立一个页面,接受用户的输入信息并发送给后端。
《构建微服务》一书作者 Sam Newman 的文章中有详细说明。
BFF产生的技术背景和历史背景
为了知道为什么需要BFF,有必要了解“应用程序的内部结构随着时代的发展而不断变化”的背景。
传统的 Web 应用是基于 HTML,功能比较简单。尤其是CGI为主的时候,很多应用都是主要由HTML构成,JavaScript只做一些交互。这个时代的 Web 应用服务器通常是一个 单体式应用程序 (Monolithic application),从数据库交互到 HTML 构建的所有工作都在这一个服务器完成。
graph LR
Browser --> node1[Monolithic Web Application] --> node21[Database]
node1 --> node22[Full Text Search]
node1 --> node23[NFS]
在21世纪初,使用 JavaScript 进行 HTTP 请求的Ajax 通信概念开始普及,Web 应用逐渐变得丰富,且具有更强的交互性。随着富Web应用数量的增加,以及更多的处理集中在了客户端,服务器端越来越多地使用了仅发送和接收数据的 API 。
graph LR
Browser --> node1[Backend API] --> node21[Database]
node1 --> node22[Full Text Search]
node1 --> node23[NFS]
此外,随着除 Web 应用之外的客户端(例如移动应用)数量的增加,服务器端需要构建专注于某一个领域的 API。它已经演变为“专门处理特定资源的架构”,因为它被称为微服务。
graph LR
Browser --> node11[User API]
Browser --> node12[Diary API]
Browser --> node13[Image API]
Mobile[Mobile App] --> node11
Mobile --> node12
Mobile --> node13
node11--> node21[Database]
node12 --> node22[Full Text Search]
node13 --> node23[NFS]
node12--> node21
node13--> node21
但是,随着客户端的更加多样化,创建满足所有客户端需求的 API 服务器变得越来越困难。你创建的移动应用和 Web 应用,UI 也各不相同,不同的客户端上所需要展现的内容也可能不同。例如,你创建了一个 Web 应用,由于屏幕尺寸的不同,用户可以看到的信息在 PC 和智能手机上可能会有所不同,甚至 UI 可能与移动应用完全不同。
此外,Web 应用具有环境限制,例如在 HTTP/1.1 中可以同时请求的请求数限制为 6。
针对这些情况,出现了一种架构,将响应每个客户端请求的服务器放置在前端,充当与后端API服务器的桥梁。这是因为 BFF 具有构建 HTML 和减少请求数量等优点。
graph LR
Browser --> node01[Web App's BFF]
Mobile[Mobile App] --> node02[Mobile App's BFF]
node01 --> node11[User API]
node01 --> node12[Diary API]
node01 --> node13[Image API]
node02 --> node11
node02 --> node12
node02 --> node13
node11--> node21[Database]
node12 --> node22[Full Text Search]
node13 --> node23[NFS]
node12--> node21
node13--> node21
这样,一种叫做“BFF”的架构就诞生了。
前端工程师还是后端工程师,谁来负责?
BFF 通常由负责客户端的前端工程师开发。由于BFF是服务器,可能会认为会由后端工程师开发,但既然是帮助构建和操作UI的服务器,那就是前端工程师的职责范围.
在 BFF 架构中,后端工程师负责基于 API 管理资源。
BFF的具体制作方法将在下一篇的“如何制作BFF”中详细说明。
何时使用 BFF 架构模式,何时不使用
BFF架构模式具有“通过前端专用的服务器使UI构建变得更容易”和“通过前后端之间的边界来划分架构层次,明确角色”的效果。可以使前后端更容易独立进行开发。
BFF架构模式在“拥有后端和前端团队,各自独立进行开发”时非常有效。当“需要支持多个客户端并且每个客户端使用相同的 API”时,BFF 也可以将 API 组合在一起。在 Web 应用中,它也可以用于构建 HTML。
当不采用 BFF 模式时,情况正好相反。进行单体模式(Monolithic Pattern)的开发,扩大开发者的职责范围可以缩短开发周期,提高开发效率。当只有一种类型的客户端时,由后端服务器来构建 HTML 或为特定客户端构建 API ,没有 BFF 也是可以的。
BFF的适配性,根据开发团队的组织架构和开发目标的不同而不同,因此是否采用BFF,可以因地制宜。
BFF 案例研究-Netflix、Twitter、Recruit
下面介绍几个 BFF 的具体案例。
Netflix 案例
在命名为 BFF 之前,Netflix 使用了类似的架构。截至 2012 年,Netflix 的技术博客“Embracing the Differences : Inside the Netflix API Redesign”以“客户端适配器(Client Adapter)”的名义介绍了它。
以 BFF 为名的架构是最近才流行起来的。事实上,许多公司已经实践了很长时间。特别是对于 Netflix,它在各种各样的客户端运行,包括 PC 、移动设备、游戏机和汽车导航系统等设备。由于客户端的多样性,使得用一个 API 适配所有客户端(“一刀切”)是相当困难的,因此引入了这种 Client Adapter 模式。
推特案例
Twitter 为移动网络创建了一个名为“Twitter Lite”的应用,该应用也是使用 BFF 架构构建的。
后端 API 是作为微服务构建的,采用的技术是 Scala 。 Web 应用展示页面时,使用了 Node.js 来组织后端 API。
Twitter 最初是使用 Ruby on Rails 作为单体服务器(Monolithic Server)构建的。随着时间的推移,用户规模不断扩充,最初的架构逐渐不能满足规模的扩张。于是采用Scala将后端重构为微服务,并且采用BFF作为优化UI / UX的机制,以符合当前架构的最新趋势。
详情请参考 Twitter 的技术博客“How we built Twitter Lite”。
Recruit 案例
Recruit 已经在实践 BFF的路上。例如,一个名为“预订表”的产品就是用 BFF 构建的。此外,SNS、问卷应用、日程管理应用等也是BFF架构。
基本上,它通常是用下图构建的。
BFF 层是使用 Node.js 构建的,它负责将 API 组合在一起并渲染 HTML 。这里有几个原因,但最主要的原因是Node.js 和前端的 JavaScript使用相同的语法。后端API通常是用Java和Go等语言开发的,这些语言是有类型的,易于管理数据。
预约表应用使用的技术在2016 Node学园祭和Recruit Lifestyle博客中有介绍,请参考。
下一篇文章中将解释 BFF 的具体构建方法。
下一篇,前端工程师如何做BFF
这一篇中,我们讲解了BFF的定义和产生背景、案例等。 BFF 并不新鲜,有的公司已经使用了很长时间,也有一些公司正在这样做。
我认为 BFF 的名称在最近几年出现的背景是“一方面服务器端作为微服务正在减少其功能,另一方面对客户端的要求越来越多。”与此同时,前端工程师不再只开发客户端,也开始参与发服务器端开发。
但是,我认为很多人还不习惯,因此我将在下一篇文章中根据实际案例介绍“如何实现它”。敬请期待。