前后端分离的项目开发策略已经不是什么新鲜东西了,网上介绍这方面的文章非常多。我自己是在14年的时候接触到的,对这种开发策略一直爱不释手,不管新老项目都会首先用前后端分离的思维先去思考一番。从14年到现在在前后分离上面也实践了近3年的时间,项目大大小小的也差不多4,5个吧,但是却从来没有一个是自己觉得很满意的,其中的原由和心酸可能只有自己才能体会了。

前后端分离实践有感

现在到处都是前后端分离的实践。然而一些项目在从一体化 Web 设计转向前后端分离的架构时,仍然会碰见各种各样的问题。由于层出不穷的问题,甚至会有团队质疑,一体化好好的,为什么要前后端分离?

首先看看前后端分离是什么?

“前端”通常指的是,相对来说更接近用户的一端,例如:APP,网页、桌面程序等,在现实开发中大部分情况可以理解为“客户端”;

“后端”相对来说就更泛化了,可以理解为是为前端提供服务的一端。

”分离“顾名思义就是将”前端“和”后端进行分开“,但是这里的分开主要从下面几个纬度进行分离

  1. 架构分离,前端不需要依赖后端架构同时后端也不需要知道前端使用何种架构
  2. 人员分离,前端后端使用的技术相互之间根部不需要相互了解完全可以在做到透明(当然相互了解会更好)
  3. 工作分离,基于项目或者产品的单个功能的横向进行工作分离,任务划分更细
  4. 关注点分离,前端偏向用户,后端偏向系统本身

下面分别是一体式web架构示意图和前后分离式web架构。

一体式 Web 架构示意

一体式 Web 架构示意

为什么要前后端分离

下面讲讲什么时候需要前后端分离,即前后端分离的应用场景。

说起这个问题,我想到了多年前,公司在以 .NET 开发团队为主的基础上扩展了 Java 团队,两个团队虽然是在做不同的产品,但是仍然存在大量重复性的开发,比如用 ASP.NET WebPage 写了组织机构相关的页面,用 JSP 又要再写一遍。在这种情况下,团队就开始思考这样一个方案:如果前端实现与后端技术无关,那页面呈现的部分就可以共用,不同的后端技术只需要实现后端业务逻辑就好。

方案根本要解决的问题是把数据和页面剥离开来。应对这种需求的技术是现成的,前端采用静态网页相关的技术,HTML + CSS + JavaScript,通过 AJAX 技术调用后端提供的业务接口。前后端协商好接口方式通过 HTTP 提供,统一使用 POST 谓词。接口数据结构使用 XML 实现,前端 jQuery 解析 XML 很方便,后端对 XML 的处理工具就更多了如JSON 。

这种架构从本质上来说就是 SOA(面向服务的架构)。当后端不提供页面,只是纯粹的通过 Web API 来提供数据和业务交互能力之后,Web 前端就成了纯粹的客户端角色,与 WinForm、移动终端应用属于同样的角色,可以把它们合在一起,统称为前端。以前的一体化架构需要定制页面来实现 Web 应用,同时又定义一套

WebService/WSDL 来对 WinForm 和移动终端提供服务。转换为新的架构之后,可以统一使用 Web API 形式为所有类型的前端提供服务。至于某些类型的前端对这个 Web API 进行的 RPC 封装,那又是另外一回事了。

通过这样的架构改造,前后端实际就已经分离开了。抛开其它类型的前端不提,这里只讨论 Web 前端和后端。由于分离,Web 前端在开发的时候压根不需要了解后端是用的什么技术,只需要后端提供了什么样的接口可以用来做什么事情就好。前后端分离之后,由于技术和业务都更专注,开发效率也提高了。分离带来的好处渐渐体现出来:

1. 前后职责分离

前端倾向于呈现,着重处理用户体验相关的问题;后端则倾处于业务逻辑、数据处理和持久化等。在设计清晰的情况下,后端只需要以数据为中心对业务处理算法负责,并按约定为前端提供 API 接口;而前端使用这些接口对用户体验负责。

2. 前后技术分离

前端可以不用了解后端技术,也不关心后端具体用什么技术来实现,只需要会 HTML/CSS/JavaScript 就能入手;而后端只需要关心后端开发技术。

3. 前后分离带来了用户用户体验和业务处理解耦

前端可以根据用户不同时期的体验需求迅速改版,后端对此毫无压力。同理,后端进行的业务逻辑升级,数据持久方案变更,只要不影响到接口,前端可以毫不知情。

前后端分离架构

任何技术方案都不是万能的,前后端分离带来了好处,同时也带来矛盾。我们在实践初期,由于前端团队力量相对薄弱,同时按照惯例,所有业务处理几乎都是由后端来设计的,前端处理过程中常常发现接口定义不符合用户操作流程等问题。毕竟后端思维和前端思维还是有所不同——前端思维倾向于用户体验,而后端思维则更倾向于业务的技术实现。

除此之外,由于前后分离本质上是一种 SOA 架构,所以在授权上也需要按 SOA 架构的方式来思考。Cookie/Session 的方式不是特别合适,相对来说,基于 Token 的认证则更适合一些。采用基于 Token 的认证就意味着后端的认证部分需要重写……后端当然不想重写,于是会将皮球踢给前端……于是前端开始报怨(悲剧)……

谁来主导

这些矛盾的出现,归根结底在于设计不够清晰明确。一般在开发过程中,主导者应该是架构师。然而大部分场景中,架构师往往也是开发人员,所以他们的主要技术栈会极大的影响前后端在整个项目中的主次作用。这位骨干处于哪端,开发的便捷性就会向哪端倾斜。这是一个不好的现象。

如果没有良好的流程规范,多数应用产品的开发通常前端接触的到角色会比后端更多。

  1. 前端开发人员会受到产品经理或客户的影响:这个地方应该放个按钮……;
  2. 前端还要与美工对接——这样的设计不好实现,是否可以改成那样?客户要求必须这么操作,但是这个设计做不到;
  3. 前端还要跟后端对接

换句话说,前端可以成为项目沟通的中心,因此前端比后端更合适承担主导的角色。

接口设计

接口分后端服务实现和前端调用两个部分,技术上并不难,因为都是成熟的技术,接口设计才是难点。前面提到前后端会产生一些矛盾。从前端的角度来看,重点关注的是用户体验;而从后端的角度来看,重点关注的是数据完整、有效、安全。解决这些矛盾的着眼点就是接口设计。

接口设计时,其粒度的大小往往代表了前后端工作量的大小:接口粒度太小,前端要处理的事情就多,尤其是对各种异步处理就可能会感到应接不暇;粒度太大,就会出现高耦合,降低灵活性和扩展性,当然这种情况下后端的工作就轻松不了。业务层面的东西涉及到具体的产品,这里不多做讨论。这里主要讨论一点点技术层面的东西。

就形式上来说,Web API 可以定义成 REST,也可以是 RPC,只要前后端商议确定下来就行。更重要的是在输入参数和输出结果上,最好一开始就有相对固定的定义,一般来说取决于前端架构或采用的 UI 框架。

常见请求参数的数据形式如下所示:

  1. 键值对,用于 URL 中的 QueryString 或者 POST 等方法的 Payload
  2. XML/JSON/...,通常用于 POST 等方法的 Payload
  3. ROUTE,由后端路由解析 URL 取得,在 RESTful 中常用

而服务器响应的数据形式就更多了,通常一个完整的响应需要包括状态码、消息、数据三个部分的内容,其中

  • 状态码:HTTP 状态码或响应数据中特定的状态属性
  • 消息:通常是放在响应内容中,作为数据的一部分
  • 数据:根据接口协议,可能是各种格式,当前最流行的是 JSON

我们在实践中使用 JSON 形式,最初定义了下面这种形式

code 主要用于指导前端进行一些特殊的操作,比如 0 表示 API 调用成功,非0 表示调用失败,其中 1 表示需要登录、2 表示未获取授权……对于这个定义,前端拿到响应之后,就可以在应用框架层进行一些常规处理,比如当 code 为 1 的时候,弹出登录窗口请用户在当前页面登录,而当 code 为 2 的时候,则弹出消息提示并后附链接引导用户获取授权。

一开始这样做并没有什么问题,直到前端框架换用了 jQuery EasyUI。以 EasyUI 为例的好多 UI 库都支持为组件配置数据 URL,它会自动通过 AJAX 来获取数据,但对数据结构有要求。如果仍然采用之前设计的响应结构,就需要为组件定义数据过滤器(filter)来处理响应结果,这样做写 filter 以及为组件声明 filter 的工作量也是不小的。为了减少这部分工作量我们决定改一改接口。

新的接口是一种可变结构,正常情况下返回 UI 需要的数据结构,出错的情况则响应一个类型于原定结构的数据结构:

对于新响应数据结构,前端框架只需要判断一下是否存在 error 属性,如果存在,检查其 identity 属性是否为指定的特殊值,然后再使用其 code 和 message 属性处理错误。这个错误判断过程略为复杂一些,但可以由前端应用框架统一处理。

使用 RESTful 风格的接口,部分状态码可以用 HTTP 状态码代替,比如 401 表示需要登录,403 就可以表示没有获得授权,当然,虽然 HTTP 状态码与 RESTful 风格更配,但是非 RESTful 风格也可以使用 HTTP 状态码来代替 error.code。

用户认证

认证方案很多,比如 Cookie/Session 在某些环境下仍然可行、也可以使用基于 Token 和 OAuth 或者 JWT,下面是几种方案的介绍。

a.基于 OAuth 的认证方案

目前各大网站的开放式接口都是 SOA 架构,如果把这些开放式接口看作提供服务方(服务端),而把使用这些开放式接口的应用看作客户端,那么就可以产生这样一种和前后分离对应的关系:

所以,开放式接口广泛使用的 OAuth 方案用于前后分离是可行的,但在具体实施上却并不是那么容易。尤其是在安全性上,由于前端是完全暴露在外的,与 OAuth 通常实施的环境(后端⇌服务端)相比,要注意的是首次认证不是使用已注册的 AppID 和 AppToken,而是使用用户名和密码。

b.基于 Token/JWT 的认证方案

虽然这个方案放在最后,但这个方案却是目前前后端分离最适合的方案。基于 Token 的认证方案,各种讨论由来已久,而 JWT 是相对较为成熟,也得到多数人认可的一种。从网上可以找到各种技术栈的 JWT 实现,应用起来也比较方便。

前后端分离的测试

前后分离之后,前端的测试将以用户体验测试和集成测试为主,而后端则主要是进行单元测试和 Web API 接口测试。与一体化的 Web 应用相比,多了一层接口测试,这一层测试可以完全自动化,一旦完成测试开发,就能在很大程度上控制住业务处理和数据错误。这样一来,集成测试的工作量会相对单一也容易得多。

前端测试的工作相对来说减轻不了多少,前后分离之后的前端部分承担了原来的集成测试工作。但是在假设 Web API 正确的情况下进行集成测试,工作量是可以减轻不少的,用例可以只关注前端体验性的问题,比如呈现是否正确,跳转是否正确,用户的操作步骤是否符合要求以及提示信息是否准确等等。

对于用户输入有效性验证这部分工作在项目时间紧迫的情况下甚至都可以完全抛给 Web API 去处理。不管是否前后端分离,Web 开发中都有一个共识:永远不要相信前端!既然后端必须保证数据的安全性和有效性,那么前端省略这一步骤并不会对后端造成什么实质性的威胁,最多只是用户体验差一点。但是,如果前后端都要做数据有效性验证,那一定要严格按照文档来进行,不然很容易出现前后端数据验证不一致的情况(这不是前后分离的问题,一体化架构同样存在这个问题)。

小结

总的来说,前后分离所带来的好处还是很明显的。但是具体实施的时候需要一个全新的思考方式,而不是基于原有一体化 Web 开发方式来进行思考。

作者:Alukar

链接:https://www.jianshu.com/p/3c7dafdc3576

若依前后端分离如何写移动端接口_前后端分离实践的架构设计相关推荐

  1. 若依前后端分离如何写移动端接口_前后端分离后,如何定义接口规范~

    小Hub领读: 前后端分离的趋势下,该怎么定义规范,来学习学习吧哈! 作者:猿码架构 www.jianshu.com/p/c81008b68350 1. 前言 随着互联网的高速发展,前端页面的展示.交 ...

  2. 若依前后端分离如何写移动端接口_前后端分离架构概述

    1.背景 2.未分离时代(各种耦合) 3.半分离时代 4.分离时代 5.总结 <Netty 实现原理与源码解析 -- 精品合集> <Spring 实现原理与源码解析 -- 精品合集& ...

  3. 冷热分离和直接使用大数据库_用读写分离与分表分库解决高访问量和大数据量...

    原标题:用读写分离与分表分库解决高访问量和大数据量 一. 数据切分 关系型数据库本身比较容易成为系统瓶颈,单机存储容量.连接数.处理能力都有限.当单表的数据量达到1000W或100G以后,由于查询维度 ...

  4. 前苹果M1芯片设计总监跳槽英特尔 或将负责所有SoC架构设计

    1月7日消息,据国外媒体报道,按计划,苹果Mac产品线所需的处理器,从2020年的M1开始经过两年的过渡期之后,就将全面转向自研M系列芯片,届时英特尔处理器就不会被采用,但在两年的过渡期即将结束时,却 ...

  5. 冷热分离和直接使用大数据库_智能冷热分离的思考-内存数据库

    冷热分离一直是数据库和存储领域离不开的话题,特别是大数据的年代,数量和存储成本的矛盾需要冷热分离来解决.对于生产系统,不同数据库的特点不同,冷热分离机制和算法也不同.本篇文章讲一下内存数据库的冷热分离 ...

  6. php写的微信聊天界面,浅谈 聊天界面 核心架构设计

    本文以一个小例子简单的演示在微信小程序中使用环信SDK收发消息.官网demo 下载后把整个utils目录下的文件复制到咱自己工程的目录下.在WebIMConfig.js中将AppKey替换成自己应用的 ...

  7. 使用SpringBoot + Vue (若依前后端分离版) 写项目的一些总结(持续更新...)

    使用SpringBoot + Vue(若依前后端分离版) 写项目的一些总结 获取Redis服务 @Autowired private RedisCache redisCache; String cap ...

  8. 后端传前端中文显示都是问好_前后端分离,后台返回的数据前端没法写,怎么办?...

    看到大家吊打后端,我来歪个楼. 首先,对于题主描述的 PHPer 吊打无疑,但并不是所有接口都可以随心所欲按照前端的要求来做,目前主要遇到几类接口: 1. 代理其他系统接口过来的(没法改底层,要转换需 ...

  9. yii2 后台权限验证获取用户身份_前、后端分离权限控制设计与实现

    作者:佚名 来源:Web开发 简述 近几年随着react.angular.vue等前端框架兴起,前后端分离的架构迅速流行.但同时权限控制也带来了问题. 网上很多前.后端分离权限仅仅都仅仅在描述前端权限 ...

最新文章

  1. BS-XX-007基于JSP实现户籍管理系统
  2. 面向切面编程-日志切面应用
  3. Autolisp:利用AuoCAD之Lisp编程案例之自动智能绘制枫叶玫瑰
  4. inbound connection timed out (ORA-3136)错误诊断
  5. Tomcat监控xml ,当修改xml后,不用重启tomcat
  6. 聊聊并发(四)深入分析ConcurrentHashMap
  7. NetworkOnMNetworkOnMainThreadException
  8. 电大计算机网考上机操作题,电大计算机上机考试模拟题及答案 (1)
  9. p沟道mos管导通条件_打开知识大门的捷径!MOS管基本认识
  10. Error running ‘Tomcat‘: Unable to open debugger port (127.0.0.1:2148): java.net.SocketExceptio
  11. Odoo10教程---模块化三:模型约束,高级视图,工作流,安全性,向导,国际化和报表等
  12. Flask初级(十)flash与前台交互post详解
  13. C++中,如何定义和使用指向成员函数的指针
  14. overleaf表格_latex插入表格心得
  15. c语言选猴王链表,C语言程序设计-猴子选大王[链表应用]
  16. pythonforandroid下载中文_SL4A、PythonForAndroid和Android 7.0 Noug
  17. Android进程系列1---进程基础
  18. Flixel横板游戏制作教程(九)—SquashingthePlayer(挤压Player)
  19. 敏捷实践之回顾会议Retro
  20. Android加速度传感器原理

热门文章

  1. hibernate连接mysql数据库步骤_Hibernate (操作步骤)
  2. 网页制作代码模板_简单的学生个人网页制作教程
  3. 【开源方案共享】VDO-SLAM:基于视觉的动态SLAM感知系统
  4. Vue子组件调用父组件方法并传参的5种方式:$emit触发、传入子组件function、访问父组件$parent.function、用inject关联父组件provide的方法、用window.fun
  5. 设置echarts的grid、tooltip、柱状图渐变色、折线图渐变色
  6. Redis在CentOS 6.8中的安装方法,JAVA初级使用Redis连接池
  7. Ubuntu 常用操作
  8. 递归/回溯:八皇后问题N-Queens
  9. Numpy学习笔记(下篇)
  10. centos 系统使用verdaccio搭建npm私库