架构系列八(前后端分离接口规范设计)

462 阅读4分钟

痛点一:前后端联调,没有任何接口约定规范,导致联调成本比较高,工作量往往增加30%-50%

痛点二:web1.0时代,前端开发环境依赖后端,难以本地化,严重影响研发效率

痛点三:web1.0时代,职责不清晰,往往在JSP中有大量业务代码,难以维护

痛点四:后端MVC时代,前端依赖后端,关注点隔离不够,比如controller中的页面路由,本该前端关注,在mvc中却是后端在处理

痛点五:前端为主的MV*时代,前后端代码不能复用,比如校验;全异步,对SEO不友好;

解决方案:Node全栈时代

image.png

  • Front-end UI layer 处理浏览器层的展现逻辑。通过 CSS 渲染样式,通过 JavaScript 加入交互功能,HTML 的生成也能够放在这层。详细看应用场景
  • Back-end UI layer 处理路由、模板、数据获取、cookie 等。通过路由,前端最终能够自主把控 URL Design,这样不管是单页面应用还是多页面应用。前端都能够自由调控。后端也最终能够摆脱对展现的强关注,转而能够专心于业务逻辑层的开发
  • 通过 Node,Web Server 层也是 JavaScript 代码,这意味着部分代码可前后复用,须要 SEO 的场景能够在服务端同步渲染。因为异步请求太多导致的性能问题也能够通过服务端来缓解

感悟:团队协作,讲究职责清晰、分工合理高效;让合适的人做合适的事

1.前后端如何实现分离

1.1.职责分离

image.png

  1. 前后端仅仅通过异步接口(AJAX/JSONP)来编程
  2. 前后端都各自有自己的开发流程,构建工具,测试集合
  3. 关注点分离,前后端变得相对独立并松耦合

image.png

1.2.开发流程

  1. 后端编写和维护接口文档,在 API 变化时更新接口文档
  2. 后端根据接口文档进行接口开发
  3. 前端根据接口文档进行开发 + Mock平台
  4. 开发完成后联调和提交测试

image.png

1.3.具体实施

现在已基本完成了,接口方面的实施:

  1. 接口文档服务器:可实现接口变更实时同步给前端展示;
  2. Mock接口数据平台:可实现接口变更实时Mock数据给前端使用;
  3. 接口规范定义:很重要,接口定义的好坏直接影响到前端的工作量和实现逻辑;具体定义规范见下节;

image.png

2.接口规范

2.1.规范原则

1.接口返回数据即显示:前端仅做渲染逻辑处理

2.渲染逻辑禁止跨多个接口调用

3.前端关注交互、渲染逻辑,尽量避免业务逻辑处理的出现

4.请求响应传输数据格式:json,json数据尽量简单轻量,避免出现多层级

2.2.基本格式

2.2.1.请求基本格式

GET请求、POST请求

  • 必须包含key为body的入参
  • 请求报文协议:json
  • 并存放到入参body中,示例如下:
#get
xxx/login?body={"username":"root","password":"root","captcha":"scfd"}
​
#post

image.png

2.2.2.响应基本格式

{
    code: 200,
    data: {
        message: "success"
    }
}
  • code : 请求处理状态
200: 请求处理成功500: 请求处理失败401: 请求未认证,跳转登录页406: 请求未授权,跳转未授权提示页
  • data.message: 请求处理消息
code=200 且 data.message="success": 请求处理成功
​
code=200 且 data.message!="success": 请求处理成功, 普通消息提示:message内容
​
code=500: 请求处理失败,警告消息提示:message内容
​

2.3.响应实体格式

data.entity: 响应返回的实体数据

{
    code: 200,
    data: {
        message: "success",
        entity: {
            id: 1,
            name: "XXX",
            code: "XXX"
        }
    }
}

2.4.响应列表格式

data.list: 响应返回的列表数据

{
    code: 200,
    data: {
        message: "success",
        list: [
            {
                id: 1,
                name: "XXX",
                code: "XXX"
            },
            {
                id: 2,
                name: "XXX",
                code: "XXX"
            }
        ]
    }
}

2.5.响应分页格式

data.recordCount: 当前页记录数 data.totalCount: 总记录数 data.pageNo: 当前页码 data.pageSize: 每页大小 data.totalPage: 总页数

{
    code: 200,
    data: {
        recordCount: 2,
        message: "success",
        totalCount: 2,
        pageNo: 1,
        pageSize: 10,
        list: [
            {
                id: 1,
                name: "XXX",
                code: "H001"
            },
            {
                id: 2,
                name: "XXX",
                code: "H001"
            } ],
        totalPage: 1
    }
}

2.6.特殊内容规范

2.6.1.下拉框、复选框、单选框

由后端接口统一逻辑判定是否选中,通过isSelect标示是否选中,示例如下:

{
    code: 200,
    data: {
        message: "success",
        list: [{
            id: 1,
            name: "XXX",
            code: "XXX",
            isSelect: 1
        }, {
            id: 1,
            name: "XXX",
            code: "XXX",
            isSelect: 0
        }]
    }
}

禁止下拉框、复选框、单选框判定选中逻辑由前端来处理,统一由后端逻辑判定选中返回给前端展示;

2.6.2.布尔类型

关于Boolean类型,JSON数据传输中一律使用1/0来标示,1为是/True0为否/False

2.6.3.日期类型

关于日期类型,JSON数据传输中一律使用字符串,具体日期格式因业务而定

最后阶段就是==Node 带来的全栈时代==,完全有前端来控制页面,URL,Controller,路由等,后端的应用就逐步弱化为真正的数据服务+业务服务,做且仅能做的是提供数据、处理业务逻辑,关注高可用、高并发