我眼中的前后端分离

本贴最后更新于 2204 天前,其中的信息可能已经天翻地覆

在我映像中,2014 年淘宝系大肆宣传他们的前后端分离架构,AngularJS 那时也发展得如火如荼。基于这一春风,业界也全方位兴起了前后端分离的热潮。但和 微服务 一样,一个名词出来了,各种各样的解读也出来了,似乎也没有人能够很清楚地说明白,前后端分离究竟如何分离。

当时我在 ZTO,大家对这个概念的理解也多种多样。那时我们各种内部系统间通过 API 调用已经是很普遍的事情,甚至已经有了开放平台的雏形,我们内部也在制定各种 API 的内部标准。而各个系统可以通过 调用API、组装数据,渲染视图 成为一套独立的系统供用户使用。那么这算不算前后端分离?当时我负责的官网产品线就很典型:

front-backend-slice-2018316183027

根据当时我们的业务场景,官网是需要有 SEO 的,我们内部有一个约定:内部业务 API 是不做授权鉴权的,需要暴露到外网的 API 才需要做鉴权。在这样的环境下,我们的方案自然就是 Web 服务调用后端 API,将数据在 Server 端处理好,并渲染好页面进行返回。

在这样的模式下,其实是将大量可复用逻辑进行了接口化开发,也可以认为是 SOA 的架构模式,这样的架构模式下门面层负责的就是 API 调用和数据组装,视图渲染。大量的业务逻辑依旧由后端程序员完成。我认为这也算一种前后端分离,至少它将视图渲染模块和数据提供模块进行了解耦。曾经一个单号跟踪查询需要写 200 多行查询语句到程序里还要到处维护的日子我再也不想体会了。

后来一些人认为,前后端分离一定要将前后端的工作分开。前端开发人员直接开发 UI,后端仅仅需要提供 Rest API 就好了。对于这种思想,我认为从分工的角度是非常合理的。毕竟分工细化是工程化的进步。这样的架构如下:

front-backend-slice-2018316221540

这种架构模式 Application Server 以及以上部分由后端程序员负责,前端程序员负责浏览器部分。感谢这些年丰富的前端框架,将页面构造工作量降低了不知多少个数量级,将视图引擎这一重要组件交由前端。后端工程师终于有了机会将视图渲染工作统统甩锅。另一方面,专业的事情交给专业的人来做,前端工程师当然会开发出更适合前端使用的工具,适合前端应用的语言。例如 PUG(jade),less,stylus 这样的语言确确实实让我感受到了 UI 开发的便利。这种开发模式下,最具革命性的地方在于工作完全解耦,不同的工程师可以各司其职。犹记当年我的前端搭档需要到我的 cshtml 文件里修改东西,还要安装一个 Visual Studio ,简直不要太悲伤。在功能开发方面,同样带来了很多便利,一些 UI 状态维护(例如当前所在菜单高亮)这种事情,从前的后端渲染时处理起来也尤为恶心,你需要关注一些和你业务逻辑并不相关的状态,这种悲催的体验随着前端完全掌控视图渲染几乎消亡。

话又说回来,其实这样的开发方式并不能算是多大的创新。在前后端分离轰轰烈烈开展之前,我想很多道友应该也用过例如 Jquery UI,ExtJs,YUI 之类的框架了吧。在很多后台管理型站点中,这样的技术已经非常普遍了。而那个年代,node.js 还没有兴起,各大厂商还在为步子太大扯到蛋的 ES5 争吵不休,bable 还没有影子,前端还没有成一个普遍认同的工种,我们还在为 IE6 而苦恼。在那个条件下,兼容性、性能、流量等等因素制约着前端的领土,一直到了移动互联的时代到来,UI 交互日益复杂,工具链逐渐成熟后,前端的美好时代终于到来。

这种开发模式也不是没有问题,首先,这种协作方式预设了一个前提:前后端开发人员是分离的。这是理想很丰满现实很骨感的典型事例啊!目前能配备一个项目至少一个专职前端的公司估计少得可怜吧,全栈工程师的概念对于一个花钱养人的 BOSS 来说应该具有无比的诱惑吧。而前后端分离也同样早就了前后端工具链的分离。原本一个 IDE,一个端口就能完成的工作现在变成了两个 IDE,两个端口;还引入了跨域问题。你说有 IDE 插件可以启动 WebPackDevServer 可以解决跨域问题。但过去根本没有这些问题的呀!

另一方面,前后端分离后部署问题也让我哭笑不得。一些人认为:应该使用 Nginx 跑代理来将前后端代理到一个域下来处理跨域问题。我个人是不太喜欢这种方案的,明明分离的优势就在于解耦,之前跨过了千辛万苦都解耦了,最后一公里又要耦合在一起?还引入了 Nginx 黑魔法在中间? 另一些人认为:可以将后台部署为 CORS 接口;这群人往往更激进,都用 CORS 了,还要中间那个 Application Server 作甚?直接捞数据 API 不就好了嘛?你看 PGSQL 都直接提供 Rest 功能了诶。但是这样的架构会不会新增运维负担?上线时还要关注请求发起方的域名,会不会引起一些额外的攻击?如果调用了不同的 API 授权鉴权怎么做?

同时,这样的前后端分离也带来了一些广泛而难以解决问题:首页面白屏时间长的问题怎么办?最要命的还在于 SEO 这一死穴让纯粹的前后端分离变得困难重重。

随着 Node.js 的发展,前端工程师也一定不会满足于浏览器这一亩三分地,在一些规模较大的组织内,一定会存在海量可复用的业务逻辑 API。那既然前后端协作还有那么多麻烦,而且搜索引擎那么排斥 ajax ,我们不如干脆把后端也做了吧。随着各大框架推出了自己的 SSR 方案,前端工程师们吹响了进军后端的号角。现在的架构变成了这样:

front-backend-slice-201831623121

历史总是螺旋上升的,是不是似乎又看到了最初的架构,现在渲染工作由服务器和浏览器共同承担,当遇到了搜索引擎爬虫和浏览器初次访问时,服务器承担了渲染工作,其他时候由浏览器承担渲染工作。

目前,前后端分离的开发模式已经深入人心,但是它也依旧存在着这样那样的问题,需要开发人员权衡取舍的问题还很多。但我们可以看到,整个社区是活跃的。前后端都在互相争夺着地盘。例如微服务体系下网关的功能也越来越强大,通过简单的配置就可以实现协议转换,数据编排等功能。道友们还是得根据自身实际情况选择技术,仔细思考原理切勿跟风盲从偏听偏信,更勿裹足不前。毕竟 前端代代框架出,各领风骚几个月 前方的沙滩和后方的后浪课都在迫不及待等着你。这是我对前后端分离的一些思考和吐槽,如果能给您带来一些想法,荣幸之至。

我的微信公众号,欢迎关注
我的微信公众号

  • 后端
    44 引用 • 126 回帖 • 1 关注
  • 架构

    我们平时所说的“架构”主要是指软件架构,这是有关软件整体结构与组件的抽象描述,用于指导软件系统各个方面的设计。另外还有“业务架构”、“网络架构”、“硬件架构”等细分领域。

    139 引用 • 441 回帖
  • 前端

    前端技术一般分为前端设计和前端开发,前端设计可以理解为网站的视觉设计,前端开发则是网站的前台代码实现,包括 HTML、CSS 以及 JavaScript 等。

    247 引用 • 1347 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • Swift

    Swift 是苹果于 2014 年 WWDC(苹果开发者大会)发布的开发语言,可与 Objective-C 共同运行于 Mac OS 和 iOS 平台,用于搭建基于苹果平台的应用程序。

    34 引用 • 37 回帖 • 496 关注
  • 招聘

    哪里都缺人,哪里都不缺人。

    189 引用 • 1056 回帖
  • Caddy

    Caddy 是一款默认自动启用 HTTPS 的 HTTP/2 Web 服务器。

    10 引用 • 54 回帖 • 125 关注
  • ReactiveX

    ReactiveX 是一个专注于异步编程与控制可观察数据(或者事件)流的 API。它组合了观察者模式,迭代器模式和函数式编程的优秀思想。

    1 引用 • 2 回帖 • 124 关注
  • Bootstrap

    Bootstrap 是 Twitter 推出的一个用于前端开发的开源工具包。它由 Twitter 的设计师 Mark Otto 和 Jacob Thornton 合作开发,是一个 CSS / HTML 框架。

    18 引用 • 33 回帖 • 683 关注
  • Mobi.css

    Mobi.css is a lightweight, flexible CSS framework that focus on mobile.

    1 引用 • 6 回帖 • 689 关注
  • frp

    frp 是一个可用于内网穿透的高性能的反向代理应用,支持 TCP、UDP、 HTTP 和 HTTPS 协议。

    15 引用 • 7 回帖
  • 笔记

    好记性不如烂笔头。

    303 引用 • 777 回帖
  • BookxNote

    BookxNote 是一款全新的电子书学习工具,助力您的学习与思考,让您的大脑更高效的记忆。

    笔记整理交给我,一心只读圣贤书。

    1 引用 • 1 关注
  • Vue.js

    Vue.js(读音 /vju ː/,类似于 view)是一个构建数据驱动的 Web 界面库。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。

    261 引用 • 662 回帖 • 1 关注
  • wolai

    我来 wolai:不仅仅是未来的云端笔记!

    1 引用 • 11 回帖
  • Ruby

    Ruby 是一种开源的面向对象程序设计的服务器端脚本语言,在 20 世纪 90 年代中期由日本的松本行弘(まつもとゆきひろ/Yukihiro Matsumoto)设计并开发。在 Ruby 社区,松本也被称为马茨(Matz)。

    7 引用 • 31 回帖 • 166 关注
  • 数据库

    据说 99% 的性能瓶颈都在数据库。

    330 引用 • 614 回帖
  • C++

    C++ 是在 C 语言的基础上开发的一种通用编程语言,应用广泛。C++ 支持多种编程范式,面向对象编程、泛型编程和过程化编程。

    106 引用 • 152 回帖 • 2 关注
  • Facebook

    Facebook 是一个联系朋友的社交工具。大家可以通过它和朋友、同事、同学以及周围的人保持互动交流,分享无限上传的图片,发布链接和视频,更可以增进对朋友的了解。

    4 引用 • 15 回帖 • 449 关注
  • OAuth

    OAuth 协议为用户资源的授权提供了一个安全的、开放而又简易的标准。与以往的授权方式不同之处是 oAuth 的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此 oAuth 是安全的。oAuth 是 Open Authorization 的简写。

    36 引用 • 103 回帖 • 3 关注
  • SQLite

    SQLite 是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite 是全世界使用最为广泛的数据库引擎。

    4 引用 • 7 回帖 • 1 关注
  • 安全

    安全永远都不是一个小问题。

    189 引用 • 813 回帖 • 2 关注
  • Python

    Python 是一种面向对象、直译式电脑编程语言,具有近二十年的发展历史,成熟且稳定。它包含了一组完善而且容易理解的标准库,能够轻松完成很多常见的任务。它的语法简捷和清晰,尽量使用无异义的英语单词,与其它大多数程序设计语言使用大括号不一样,它使用缩进来定义语句块。

    534 引用 • 671 回帖
  • uTools

    uTools 是一个极简、插件化、跨平台的现代桌面软件。通过自由选配丰富的插件,打造你得心应手的工具集合。

    5 引用 • 13 回帖
  • SMTP

    SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。SMTP 协议属于 TCP/IP 协议簇,它帮助每台计算机在发送或中转信件时找到下一个目的地。

    4 引用 • 18 回帖 • 581 关注
  • Telegram

    Telegram 是一个非盈利性、基于云端的即时消息服务。它提供了支持各大操作系统平台的开源的客户端,也提供了很多强大的 APIs 给开发者创建自己的客户端和机器人。

    5 引用 • 35 回帖 • 1 关注
  • 倾城之链
    23 引用 • 66 回帖 • 93 关注
  • Electron

    Electron 基于 Chromium 和 Node.js,让你可以使用 HTML、CSS 和 JavaScript 构建应用。它是一个由 GitHub 及众多贡献者组成的活跃社区共同维护的开源项目,兼容 Mac、Windows 和 Linux,它构建的应用可在这三个操作系统上面运行。

    15 引用 • 136 回帖
  • jQuery

    jQuery 是一套跨浏览器的 JavaScript 库,强化 HTML 与 JavaScript 之间的操作。由 John Resig 在 2006 年 1 月的 BarCamp NYC 上释出第一个版本。全球约有 28% 的网站使用 jQuery,是非常受欢迎的 JavaScript 库。

    63 引用 • 134 回帖 • 744 关注
  • RIP

    愿逝者安息!

    8 引用 • 92 回帖 • 285 关注
  • 国际化

    i18n(其来源是英文单词 internationalization 的首末字符 i 和 n,18 为中间的字符数)是“国际化”的简称。对程序来说,国际化是指在不修改代码的情况下,能根据不同语言及地区显示相应的界面。

    7 引用 • 26 回帖 • 1 关注