前后端分离是目前项目开发上主流的一种模式,这个概念已经流传很长时间,在新项目开发中要实现前后端分离并没有特别的难度,但在老项目中真正要实现前后端分离却不是一朝一夕的事情,特别是在经过时间洗礼的项目中,留下了多少前辈的沉淀,历史包袱分分钟让你暴脾气。
在很多开发者相关的 APP 平台上,太多的人谈论或发表过对前后端分离的看法及经验,参考价值大的文章也不少,但大部分情况下并不能拿来主义,基本上都是具有本项目特色的一些实战方案,如何总结出一种适合自己团队的方案才是最优的选择。明道云项目的起点不算晚(8、9年前),技术选型上在当时来看并不存在什么明显的缺陷,单体程序,开发部署快,一个代码库就足够。在明道云当时也并没有前端开发和后端开发的区分,基本都叫 Web 开发工程师,前后端通吃。明道云最初采用的是微软 ASP.NET 的 WebForm 产品进行开发,前端可以夹杂后端代码,后端也可以夹杂前端代码,很强大,最终证明改造阻力也很强大。
在初期,项目上更多是业务驱动型,核心就一句话,”不要扯那么多,先做出来再说” ,站在商业的角度来看,确实非常合理,而且很多产品初期都是一样的模式,但如果随着时间的发展,对项目架构没有尽快采取改进措施,后期的重构过程中阻力将难以预估。随着明道云整体功能的和产品线的增加,越来越多的服务来支撑明道云主站项目的运行,当时人员职能划分上基本没什么变化,主站项目也依然是前后端混合体,只是在后端服务开发的语言上更多使用了当时比较火的 NodeJs。
后来随着微服务架构慢慢流行,同时更多开发小伙伴的加入和职能专业度上的更高要求,在团队成员上开始区分前端和后端开发工程师,功能模块的开发上也尽量偏向前后端分离的模式,但是随着功能的继续扩展与叠加,主站项目的后端代码接口层持续膨胀,因为太多的业务逻辑依赖关系导致新功能很难独立,这就出现了四周不断扩散的同时中间依然臃肿的状态,所以面临的问题就是不管微服务如何布局,主站项目的后端复杂度及与前端耦合度没有明显改善,如下图:
同时主站项目的代码管理和部署上的问题也越发严重,拉代码后编译就要花几分钟,改几行代码编译又得花几分钟才能跑起来进行测试,修改紧急 bug 发布上线必须全站前后端代码一起上。归根结底,项目太大,需要拆分,但拆分还得从前后端分离开始,可前后端分离并不是一蹴而就的事情,要做到一刀切是不现实的,所以这个事情在当时真的不能想,想想还不如放弃。另外和很多开发团队一样,平时产品上的新需求也很多,开发有很少时间能专注到技改上,但从长远来看,这个事情又是非干不可,所以当时定了以下几个小目标:
- 后端接口规范化,请求和返回参数都必须以 JSON 格式传输,同时返回值必须有统一的结构,如:{ “code”: int, “message”: string, “data”: object } ;
- 前端封装统一 Ajax 请求方法,不要在每个文件内单独设置请求的 host 地址,host 地址有封装的内部配置,这样的目的是为之后与后端分离后只需要修改 host 即可,如:开始是 “/api/” ,之后为 “https://getaway.mingdao.com/api/” ;
- 原来由服务端渲染的页面改造成接口提供数据由前端进行渲染;
- 原来后端实现的各种跳转逻辑全部交给前端(前端路由规则后端不需要关注);
乍一看,要做的事情并不多,但由于当时主站项目的接口写法是直接基于 aspx.cs(熟悉 .NET Framework 开发的应该知道),通过创建 aspx 页面方式,每个页面内定义一批接口,更难搞的是接口的返回格式之前完全没有规范,这也是当时团队中 Web 开发工程师的特色,缺啥我自己给,自己怎么满意怎么来,具体的代码就不拿出来了,有经验的码农朋友肯定能脑补得很形象。
所以前端的改造在很大程度上受限于后端接口的规范化,那后端的改造就成为万众瞩目的焦点。在明道云开发个人化版本架构大改造的过程中,因为涉及改动的接口实在太多,同时又有前后端分离的计划,所以最终决定还是在主站项目下另外实现一个接口层(Web.Ajax),大体实现方式是自定义了一个类似 MVC 中 Controller/Action 模式的程序集,而继续保留在主站项目下主要是考虑稳定性和时间成本,但同时也考虑到前后端分离目标,所以最终提供给前端唯一的 Ajax 请求接收的入口文件,接收 Controller 和 Action 参数,由该入口文件内通过反射的方式实现接口调用,待之后要完全分离时,改动也不复杂。
经过较长时间的改造,最终前面提到的4个方面都有了比较大的推进,基本上达到最初设定目标的 70~80% ,但由于业务的需要,接下来很长一段时间前后端分离的工作基本搁置,不过在前端本身的技术推进中实现了明道云单页模式。
随着容器化技术在明道云的推广及 .NET Core 的盛行,基于 .NET Framework 开发的主站项目就特别显得突兀,同时又因为要落地明道云私有部署版(完全基于 Docker 的容器服务),所以主站项目 .NET Framework 转 .NET Core 已是必然。虽然前后端没有完全分离,但基于之前很长时间的积累,后端优先升级为 .NET Core 并无约束,所以从 Web.Ajax 层开始截肢,Web.Ajax 及以上部分全部是迁移到主站后端 API 服务仓库下,剩下的部分暂留给前端,同时 Web.Ajax 层改造成 ASP.NET Core API 类型的应用程序,也与开始构造的类 MVC 程序集基本兼容。
经过以上调整后,主要遗留部分只剩下小目标 3,4 中的一部分,经过团队小伙伴继续相互积极配合,终于在今年初完成了全面的前后端分离工作,而且至此明道云 SaaS 版所有依赖的服务全部采用 Docker 容器化部署。
明道云前后端分离这条路走的并不顺利,中间的阻力也比描述的要大很多,而且经历了各种技术和团队上的变革,反正最终功夫不负有心人,也算是干出来了。