作者 | 郑嘉涛(羣青)
无一例外,谈到前后端分离“必定”是 RESTful API,算是定式了。但我们知道 REST 在资源划分上的设计总是与 UI 大相径庭,大量专用、特异、古怪的接口就像永远拾不尽的菌菇,你费力铲除它们,但一场雷雨便又枯树复披。另一方面接口越来越通用,最后却只剩下 CRUD,美其名曰后端只考虑稳定和性能,大量业务逻辑却全权“丢”给了前端,不禁让人怀疑,这真的是前后端分离了吗?
Erda 作为企业一站式云原生 PaaS 平台,也存在着大量面向使用交互的布局各色的界面:从个人后台到部署总览再到项目设置;从集群管理到监控大盘再到成员管理。我们从 REST 开始做起,但也逐渐发生变化。本文将从头讲述我们如何从确实问题切入,逐步建设和完善 Erda 的前后端分离框架。
由于整个框架牵涉到太多内容,所以我计划以系列文章的形式来进行详细解读。本文主要介绍其产生的缘由以及设计思路,更多相关的细节会在后续文章中进行展开,包括但不限于:
框架实现细节 使用框架后测试如何展开?
稳定性和工程管理 ······
简要介绍一下本文的主要结构:
朴素的想法 交互 vs 业务
回归经典 组件及协议
前面三个部分主要介绍了我们建设框架的背景以及方案分析,“组件及协议”部分则整体阐述了框架的核心设计理念。如果你赶时间,建议直接阅读“组件及协议”部分。
所有软件公司都会遇到的困境,那就是分工。老派开发者会信奉单打独斗全栈的能力,但软件变得复杂之后,分工是不可避免的,而最为显著的就是前后端的分工。
Erda 的前端资源一直是紧缺的,最夸张的时候前后端比例可以达到 1:8,大部分情况下,工程的瓶颈在于前端。我们很朴素的认为,改变这个局面需要后端承担更多的工作,以释放前端的人力。
所谓前后端的分工,从根本上来说是交互和业务的划分。
下图是最通用的场景,前端关注视觉、体验等,后端关注 CRUD、安全、稳定等。而业务流程、权限等则是散落在前端和后端,我们很难说清楚一个具体的业务逻辑究竟是前端实现的,还是后端实现的。
重复性工作:进而系统开发会在某些位置产生疏忽(比如前端实现了鉴权,导致后端的鉴权逻辑得不到很好的验证)。 前后端对接面积大:带来沟通成本,往往这个成本由前端同学承担,这也是前端资源短缺的原因之一。
相关链接:https://www.hey.com/how-it-works/
前后端的沟通成本大量减少,即使前后端都需要熟知业务细节。 接口调试成本大量减少,即使接口设计经过充分的评审。
放到更长远的角度,功能变更和迭代的成本也趋于减少。
浏览器发起请求,当请求得到处理,服务端传输数据给浏览器以呈现界面(这个数据一般为 HTML,一种描述呈现方式的语言)。 以表单为例,在呈现为表单的界面上进行操作,按照协议和浏览器的实现,则会发起一次新的资源请求(HTTP)。
这次请求需要服务器进行资源更改,成功后则会重新返回数据给浏览器以呈现修改后的界面。
<form action="/users/1">
<label>Name:</label>
<input type="text" name="name" value="Bob">
<input type="submit" value="Submit">
</form>
沉淀出一个通用的组件库(来扩充浏览器交互元素),并且这个组件库数量是固定的,我们将其称之为“通用组件”。 利用通用组件填充进业务数据后可以配置呈现出业务功能,比如登录表单、项目创建表单等;通用组件复合业务属性后,我们称之为“业务组件”,业务组件个数会随着业务增长而膨胀。
需要有一个协议来响应交互,达成上述 form 表单的交互流程,但是这个协议需要足够强大不仅能支持组件库所有组件的交互流程,还需要支持多组件联动的复杂场景;这个协议运行在 HTTP 之上,但是与 RESTful 的区别在于,REST 只关注数据且它是无状态的,而我们设想的协议需要感知界面呈现以及支持完整的交互流程。
丰富的通用组件库。 组件渲染能力,将业务组件渲染成通用组件。
协议渲染能力,以处理复杂交互。
业务组件渲染器:核心是处理业务数据到通用组件的转化,以及通用组件操作(operation)的处理(handle)。 场景协议渲染器:核心是将一堆组件编排成为一个场景(可以理解为一个页面,如上图右侧的页面结构)以及场景中组件之间的数据绑定,在有交互产生操作(operation)时,负责决策下派以及操作生效后的重新渲染。
业务组件真的能隔离业务吗?交互怎么办?
协议渲染真的能替换 REST 吗?我只能二选一吗?
……
推荐阅读