相信先后端分离这个词,早已流传甚广,你们一些本身的理解,但可能有些人的观点有稍许误差:咱们要搞 SPA,全AJAX,那才是先后端分离了。css
什么是先后端分离
咱们来聊聊什么是先后端分离。html
先来看一张WEB系统先后端架构模型图。前端
WEB系统先后端架构模型
从图中能够清晰的看到,先后端的界限是按照浏览器和服务器的划分。那么咱们常常会发现一些问题:git
- 模板层归属前端仍是后端?
- 模板强依赖于后端渲染,前端开发须要等待后端开发吗?
一般状况,模板层归属于前端,由于让后端人员来接触他们不擅长的样式和 js 交互是很蛋疼的事情。github
那么,做为前端开发的咱们在实际的开发场景中又会遇到如下问题:web
- 环境:进行本地开发,须要起后端环境,如 Tomcat、PHP,影响开发效率
- 流程:前端开发先开发 html,再将 html 改写成指定的模板语法(俗称套模板),影响开发效率
- 接口:
- 接口定义通常使用 word 文档,前端开发时很差理解接口字段,影响开发效率
- 接口变动须要从新编写文档,并从新发送,影响开发效率
- 文档散落,影响接口维护
- 联调:
- 联调过程变得很复杂,尤为是没有作热部署的Java工程,改视图还须要重启Tomcat,影响前端联调效率
- 效益:
- 前端开发更关注用户体验,然后端只但愿关注数据可靠,为实现如响应式、ssr之类的一些交互,前端须要掌控必定的请求响应能力
- 若是先后端对接的方式转变成为纯粹的 JSON 交换,对于提高开发效率、更清晰的职责与接口复用都是有好处的
出现影响开发效率的事情,就说明现有的模式存在问题,显然问题的解题思路须要咱们从新思考“先后端”的定义。此时,先后端分离的概念便应运而生,目的是将先后端开发人员的合做方式调节到你们都尽量温馨的姿式。后端
有哪些实现方案
SPA
SPA
全称 Single Page Application,使用前端路由的方式代替后端的 controller,并使用前端模板代替后端的模板引擎渲染,使用 restful api 实现与后端的数据交互。
在这个方案中,先后端的交互被转换成了纯粹的 http 方式的 JSON 串交互。设计模式
SPA 的优点:
- 环境:前端开发者不须要本地起后端环境
- 流程:独立的前端开发方式,因为后端返回纯 JSON ,前端想要模拟请求响应的话,只需启动一个纯静态的服务器,响应 JSON 格式的 html 便可
- 联调:清晰的对接方式,JSON 对于先后端来讲都是比较纯粹的
- 效益:对于用户来讲,用户体验的提高
SPA 的劣势
- SEO 弱
- 首屏加载慢,等全部 js 加载完才能出首屏
- 前端须要处理一些本不须要在这一层处理的事情,如权限控制交给前端控制
综上,SPA 是一个能够解决先后端分离的有效方案,对于无 SEO 要求的项目大能够尝试。api
开发阶段的分离 -- Mock && Proxy
顾名思义,开发阶段的先后端分离,须要依赖工具实现,一般把这个工具叫作 Mock Server(如笔者所开发的一款 Mock Server -- Foxman)。浏览器
Mock Server 提供功能
基础功能
- 拦截同步请求,取 JSON 格式的 Mock 数据,结合本地 Template,经过模板渲染引擎渲染,得出响应的页面
- 拦截异步请求,取 JSON 格式的 Mock 数据响应
这里咱们须要抽象以上操做为两个函数,利于理解:
- SyncView = TemplateEngine(Template, MockData)
- AsyncView = MockDataTransform(MockData)
优化功能
- Living Reload -- 监听本地文件,发生修改则通知(通常使用 websocket)浏览器更新资源
- 修改响应头 -- Mock 阶段,能够作到 js 修改响应状况
- 代理 -- 前面提到了两个函数,代理的指责是将本来取自本地的 MockData,改为了从服务端以 http 的方式取得的数据
开发流程
咱们将一个项目开发划分为三个阶段:接口定义,开发,联调。正好能够和咱们 “Mock”、 “Proxy” 两个工具契合。
让咱们经过实际的场景来表述这种先后端的合做方式。
接口定义
咱们接到一个需求,实现某个功能。在咱们理清楚具体的功能以后,应该与后端定义接口及返回,包括:
- 有哪些页面,页面的请求路径,模板位置,以及后端返回给咱们的 Model 内容
- 有哪些 Ajax 接口,Ajax接口 的请求路径,以及后端返回的 JSON 内容
在制定完接口后,咱们须要按照 Mock Server 的要求,建立 Mock 文件,并往里面填入与后端约定好的 JSON 数据,并与后端确认。
显然咱们的开发中,接口定义变成了一件很具体的事情,而开发阶段可使用这份 Mock 数据,并作到 Mock 数据即接口文档
开发阶段
在咱们完成接口定义后,咱们指望的是无打扰、自治的一个开发体验。
正如上图所示,开发阶段前端开发能够彻底与后端开发人员隔绝,也不须要本地启动后端环境,咱们要作的,只是按照先前指定的接口及本地的 Mock 文件进行需求的开发。
而在开发过程当中,遵循 html -> css -> js 的开发顺序,Foxman 拥有一个很人性化的 live reload(更改css 之会 reload css),总之接口定义合理的话,这一步会很顺畅。
联调阶段
在咱们开发完页面后,咱们指望的是与后端进行联合调试,已验证功能开发是否存在缺陷,即联调阶段。
在这步骤中,咱们只须要更换 SyncView = TemplateEngine(Template, MockData)
的 MockData,将本来响应自 Mock 文件的请求,转发到真实的目标服务器(在联调阶段会是 开发主机 或者 测试机)。
此处代理和转发,笔者已抽象成了的另一个库 koa-api-forward,欢迎交流和使用。
Mock && Proxy 优点
- 环境:
- 流程:
- 独立的前端开发方式,Mock 与 Proxy 结合,流程清晰
- 前端能够在本地调试 view 层,大幅度提高前端的联调效率
- 联调:
- 清晰的对接方式,JSON 实现先后端来讲都是比较纯粹的
- 效益:
Mock && Proxy 劣势
- 未真正掌握线上的接口响应,实现一些前端交互需求(响应式)时仍依赖后端,或没法进行(如 ssr)
Node.js 中间层
https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2017/10/5/956f5231f02144f4b6ef87a50abf2ce0~tplv-t2oaga2asx-image.image
这个模式天然时结合了前面的 Proxy。你们都知道 Node.js Server 里面强调一个 中间件的 概念,对应到设计模式的职责链模式。即只处理本身能处理的状况,不然,继续日后传递,直到被处理。
这个方案中,Proxy 做为了中间件体系中的最后一层,用以转发请求,而在这以前依次是中间件的错误处理、静态资源的响应、路由拦截(routers) 等等。
Node.js 拥有必定的接口控制能力,如处理 PC/Mobile 的响应式渲染,或是 Server-Side-Render 等等。
Node.js 中间层优点
- 环境:
- 联调:
- 清晰的对接方式,JSON 实现先后端来讲都是比较纯粹的
- 效益:
- 可渐进式,前期能够将请求所有转发后端服务器,然后能够逐步将 Node.js 层做为用户的直接数据交换层
- 职责分明,后端服务化,Node.js 层处理接口用户相关的页面响应 及 数据交换
- 可组合性,后端服务化,Node.js 负责组合拼装,实现接口可复用率
Node.js 中间层劣势
- 开发阶段仍须要 Mock 支持,若是将 Mock 方式整合进 Node.js 中间层,则形成 Node.js 中间层职责不纯粹
- 对现有系统的渐进式改造是个较为漫长的过程
总结
仍是那句话,全部的先后端分离方案,都是为了先后端开发人员的合做方式调节到你们都尽量温馨的姿式。
那么一个不错的实践是,咱们能够将 (Mock && Proxy) 与 Node.js 中间层 两个方案结合:
- Mock && Proxy 只依靠抽象出来的工具,在前端开发阶段,继续使用,避免形成 Node.js 中间层职责不纯粹
- Node.js 中间层的存在能够解决(Mock && Proxy)方案的劣势
未完待续。。。
参考资料
by 君羽