前后端对接的思考及总结

说在前面的话

随着前端NodeJs技术的火爆,现在的前端已经非以前传统意义上的前端了,各种前端框架(Vue、React、Angular......)井喷式发展,配合NodeJs服务端渲染引擎,目前前端能完成的工作不仅仅局限于CSS,JS等方面,很多系统的业务逻辑都可以放在前端来完成,例如我司的管控

那可能有些人会说,前端这么火,NodeJs发展这么迅猛,后端是不是以后都没事情干了,其实不然,拿Java来说,经过这么多年发展,已经相当稳定,完善的生态圈也非最近今年发展起来的NodeJs可比,我们常常说闻道有先后,术业有专攻,用在这里最合适不过了,集群分布式高可用等等技术还是需要后端架构师来思考的事情

目前前端同后端的合作方式是前后端分离,通过Nginx+Tomcat的组合部署(还可加nodejs中间件)方式能有效的进行解耦,并且前后端分离为项目以后的架构扩展、微服务化、组件化都打下重要基础,所以这在以后是一个发展的必然趋势,我们需要去适应,做出改变!!!

早期的开发方式

早期的开发方式如下图:

这也是我前面工作1-3年的开发方式,我们没有前端帮我们写JS函数功能,所有的页面表单验证,数据渲染,数据接口编写都是我们后端全部实现,看上去更像是一个全栈工程师,从需求分析、搭建整个技术架构、数据库表设计、功能设计、编码开发,再到最终部署上线,我们无所不在,这可能也是目前很多小公司仍然在沿用的开发方式,很多后端同学担负起了项目的方方面面

以我目前的经验来看,这样的开发方式对我个人的成长是有益无害的,因为你只有在了解了前端的JS/CSS/HTML的情况下,然后再谈目前的前后端分离,会让你的工作事半功倍,在写后端接口前,你脑子里浮现的是整个功能的交互页面,最终呈现的是前后端合作开发好后的的终端结果,这大大缩减了前后端的沟通交流

前后端分离的探索

jsonp

可能由于我在前面三年积累了丰富的前端经验,在上家公司主要负责开发官网、微信、后台等相关系统的接口,前期我们的开发方式虽然也是前后端分离的方式,但大都使用jsonp跨域接口调用的方式来达到分离效果,后端所有的接口都是可跨域调用的jsonp形式,抛开需要登录的授权之外的接口,前端在开发的时候本地无需开启服务即可调用服务端接口,然后渲染数据,完成页面交互渲染效果

jsonp的优点

不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制

兼容性更好,在更低版本的ie浏览器中都能兼容,这里区别于cors跨域类型

jsonp的原理其实很简单,当然,这也涉及到前端的知识,简单点说就是js端的function函数执行

正常的后端响应数据,例如:

{
   "code":"8200",
   "data":{
       "id":"100",
       "name":"Test"
       //more......
  }
}

jsonp需要的返回格式:


callback({
   "code":"8200",
   "data":{
       "id":"100",
       "name":"Test"
       //more......
  }
});

前端在页面定义callback回调函数,callback函数接收后端响应回来的data-json数据,后端响应后执行callback函数达到调用前端业务逻辑的目的,渲染页面

nginx+ajax

这种配合开发方式也是适合前端还没有引入Node等一站式开发解决方案的情况下引入的,纯粹的HTML+CSS+JS同后端对接,绑定业务接口,渲染数据

我们在使用JSONP开发的时候,前端都是需要在页面端写死HOST+IP接口地址,存在很重大一个弊端就是前端需要些config文件,来配置我们后端的接口请求地址,如果前端工程师规范意识强一点,会通用到一个配置文件里,但是如果没有这方面的意识的话,就会出现代码里硬编码的情况,不利于服务器迁移,代码更新,接口变动等操作

为规避上面碰到的问题,使用nginx的反向代理功能,将后端服务器代理下来,前端在开发的时候本地开启nginx服务,即解决了jsonp跨域问题,同时也解决了无需写死后端的服务ip+端口地址,利于后端在部署时整合代码,减少不必要的错误

node

随着NodeJs的火热,前端已经可以本地开启服务写接口的情况下,就类似服务端开启tomcat一样,在这样的情况下,前端框架VUE、React等都在此基础上,提供了一套完整的技术解决方案,这和上面说到的开启nginx服务架构有点类似

这样做的意义:真正的解放了前后端,专注各自擅长的领域

技术架构如下:

前端node服务直接访问后端Java Restful Api接口服务,Api接口最终访问数据库完成数据查询最终返回node层,node渲染响应数据到前端

如果存在会话信息同步等问题,可以使用中间件,例如redis缓存数据库,解决前端node和后端Api信息同步问题,传参可以通过JWT等方式完成接口权限验证

不管是jsonp还是ajax+nginx这两种方式,node作为中间件都可以轻松切换处理,而且node作为中间层,还可以将多个后端接口组合成一整个数据集,最终以同步的方式渲染前端,这也利于做SEO优化,也是前面两种方式无法做到的

关于前后端分离,详细可阅读前后端分离的思考与实践,该文章详细的列述了关于前后端分离的实际经验

谈谈接口

随着前后端的分离,后端工程师不需要编写页面,不需要写JS,只需要提供接口即可,可是就是仅仅这一个接口,对于很多后端开发工程师而言,在实际开发,同前端对接的过程中,依然问题重重

很多后端同学说我只负责写接口,其他我一概不管,这样造成的后果就是

1、接口结构无序、杂乱无章

2、接口和实际业务场景不相匹配、不可用

3、频繁的同前端沟通,简单的事情复杂化,前后端都很恼火

4、事情没做好

后端在编写接口前,首先是对业务的理解,在对业务未理解透彻之前,编码都是无意义的,作为后端来说,需要锻炼自己对整个系统全局考虑的能力,接口之间并非是毫无关联的,我们在写第一个接口之间,其他接口之间的业务逻辑也许考虑到,这在后端团队合作开发不同功能的情况下显得尤为重要.

后端在开发接口时,我觉得主要从以下几个方面需要注意:

接口url 定义

接口类型、参数

全局错误码定义

接口json格式

接口文档编写

接口url定义

对于后端开发人员来说,接口前端入参,最终组合查询数据库资源,经过一系列相关业务场景下的计算,响应给前端json数据,每一层url的path定义需要清晰明了,这和后端在使用AOP定义事务管理同理,后端service需要满足一定的命名规范,这样方便统一管理,而且有这层规范后,后续的前后端对接会轻松很多

为了在许多API和长时间内提供一致的开发人员体验,API使用的所有名称应为:

  • 简单

  • 直觉

  • 一致

这包括接口,资源,集合,方法和消息的名称。

由于许多开发人员不是英文母语人士,因此这些命名约定的目标之一是确保大多数开发人员能够轻松了解API。 它通过鼓励在命名方法和资源时使用简单,一致和小的词汇表来实现。

  • API中使用的名称应该是正确的美国英语。例如,许可证(而不是许可证),颜色(而不是颜色)。

  • 可以简单地使用常用的简短形式或长字的缩写。例如,API优于应用程序编程接口。

  • 尽可能使用直观,熟悉的术语。例如,当描述删除(和销毁)资源时,删除是优先于擦除。

  • 对同一概念使用相同的名称或术语,包括跨API共享的概念。

  • 避免名称重载。为不同的概念使用不同的名称。

  • 仔细考虑使用可能与常用编程语言中的关键字冲突的名称。可以使用这些名称,但在API审查期间可能会触发额外的审查。谨慎和谨慎地使用它们。

接口类型、参数

关于接口的请求类型,目前比较常用的:GETPOSTPUTDELETEPATCH

GET(SELECT):从服务器取出资源(一项或多项)。

POST(CREATE):在服务器新建一个资源。

PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)。

PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)。

DELETE(DELETE):从服务器删除资源。

后端可根据不同的业务场景定义不同的接口类型

在定义接口参数之时,目前我们常用的几种提交方式

表单提交,application/x-www-form-urlencoded

表单提交主要针对key-value的提交形式

如下Java片段:


@PostMapping("/queryAll")
public RestfulMessage queryAll(RuleCheckLogs ruleCheckLogs, @RequestParam(value = "current_page",defaultValue = "1")Integer current_page
          , @RequestParam(value = "page_size",defaultValue = "10")Integer page_size
          , @RequestParam(value = "tableName",required = false) String tableName){
       RestfulMessage restfulMessage=new RestfulMessage();
       try{
           assertArgumentNotEmpty(ruleCheckLogs.getProjectId(),"质检方案id不能为空"); restfulMessage.setData(qcRuleCheckLogsService.queryRuleLogsByPage(ruleCheckLogs,tableName,current_page,page_size));
      }catch (Exception e){
           restfulMessage=wrapperException(e);
      }
       return restfulMessage;
}

 

文件流提交

json提交,application/json

json提交方式在SpringMVC或Spring Boot中主要有两种,一种是以@RequestBody注解接收方式,另外一种是以HttpEntity<String> requestEntity字节接收

Java代码示例:


@PostMapping("/mergeModelEntitys")
public RestfulMessage mergeModelEntitys(HttpEntity<String> requestEntity){
   RestfulMessage restfulMessage=new RestfulMessage();
   try{
       JsonObject paramsJson = paramJson(requestEntity);
       assertJsonNotEmpty(paramsJson,"请求参数不能为空");
       //more...
  }catch (Exception e){
       restfulMessage=wrapperException(e);
  }
   return restfulMessage;
}

全局错误码定义

错误码的定义同HTTP请求状态码一样,对接者能通过系统定义的错误码,快速了解接口返回错误信息,方便排查错误原因


{
   "code": "8200",
   "message": "Success",
   "data": {
       "total_page": 1,
       "current_page": 1,
       "page_size": 10,
       "count": 5,
       "data": [
          {
               "id": "a29ab07f1d374c22a72e884d4e822b29",
               //......
          }//....
      ]
  }
}

接口json格式

后端响应json给前端需要注意以下几点:

1、json格式需固定

例如如下图形

如上图所示,横向是时间,纵向是value值

我们给出的json结构应该如此:


[
  {
       "date":"2018-01",
       "value":100
  },
  {
       "date":"2018-02",
       "value":200
  }
   //more...
]

在工作中,我们经常碰见这样的数据格式:


[
   "2018-01":{
  value:100
  },
   "2018-02":{
  value:200
  }
   //more...
]

这里所说的json格式固定主要针对此种情况,后端给到前端的接口格式必须是固定的,所有动态数据值都需相应的key与之对应

2、所有返回接口数据需直接可用,越简单越好

后端提供给前端的接口数据,最终交给前端的工作,只需要让前端渲染数据即可,越简单越好,不因掺杂过多的业务逻辑让前端处理,所有复杂的业务逻辑,能合并规避掉的都需后端处理掉.

接口文档编写

接口文档编写是前后端对接重要依据,后端写明接口文档,前端根据接口文档对接

文档形势目前主要分几种:

1、依赖swagger框架,自动生成接口文档(swagger只能生成基于key-value详细参数方式,针对json格式,无法说明具体请求内容)

2、手动编写说明文档,推荐markdown编写

接口对接

万事俱备,只欠东风,虽然上面我们准备了所有我们该准备的,接口定义完美无缺,接口文档也已说明,但在对接时任然可能出现问题,此时我想我们还需注意的细节

1、后端接口需自行进行Junit单元测试

Spring目前集成Junit框架可方便进行单元测试,包括对业务bean的方法测试,以及针对api的mock测试

@RunWith(SpringRunner.class)
@SpringBootTest
public class QcWebApplicationTests {

@Autowired
private WebApplicationContext context;

private MockMvc mvc;

@Autowired
QcFieldService qcFieldService;

@Before
public void setUp() throws Exception {
       //初始化mock对象
mvc = MockMvcBuilders.webAppContextSetup(context).build();
}

@Test
public void queryByDsId(){
try {
           //针对mock-接口Controller层测试
mvc.perform(MockMvcRequestBuilders.post("/qc/entity/queryByDsId")
                  .contentType(MediaType.APPLICATION_JSON_UTF8)
                  .param("dsId", "7d4c101498c742368ef7232f492b95bc")
                  .accept(MediaType.APPLICATION_JSON))
                  .andExpect(MockMvcResultMatchers.status().isOk())
                  .andDo(MockMvcResultHandlers.print());
} catch (Exception e) {
e.printStackTrace();
}
}
   
   @Test
   public void testUpdateField(){
QcField qcField=new QcField();
qcField.setId("513ee55f5dc2498cb69b14b558bc73e6");
qcField.setShortName("密码");
       //业务bean-service方法测试
qcFieldService.updateBatchFields(Lists.newArrayList(qcField));
}

2、使用工具测试,推荐PostMan

作为接口调试神器,Postman大名想必大家都已知道

作为后端来说,我们需要学会查看chrome推荐给我们的审查元素的功能,可参看Chrome开发工具介绍

chrome提供了一个可以copy当前接口的url功能,最终生成curl命令行

最终通过Copy as cURL(bash)功能可生成curl命令


curl 'http://demo.com/qc/ds/getAll' -H 'Origin: http://demo.com' -H 'Accept-Encoding: gzip, deflate' -H 'Accept-Language: zh-CN,zh;q=0.9' -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36' -H 'Content-Type: application/x-www-form-urlencoded' -H 'Accept: application/json, text/plain, */*' -H 'Referer: http://demo.com/index.html' -H 'Connection: keep-alive' --data 'current_page=1&page_size=6&' --compressed

以上命令可以在Linux等各终端直接执行

curl命令是一个利用URL规则在命令行下工作的文件传输工具。它支持文件的上传和下载,所以是综合传输工具,但按传统,习惯称curl为下载工具。作为一款强力工具,curl支持包括HTTP、HTTPS、ftp等众多协议,还支持POST、cookies、认证、从指定偏移处下载部分文件、用户代理字符串、限速、文件大小、进度条等特征。做网页处理流程和数据检索自动化,curl可以祝一臂之力。

postman提供导入curl命令行

3、前后端需心平气和沟通,勿推卸责任,前后端开发人员水平不尽相同,作为同事,需要的是团结合作,努力将事情做好,而非相互推卸

结语

前后端分离,简化了我们的开发方式,不同人专注于不同的领域,技术价值最大化,大大提高工作效率,我们在掌握这些技能的同时,也需要加强自身的发展,以适应当前的技术发展趋势,不管是前端还是后端,多了解一些,总是没错的,古人云:技多不压身,我想也正是此理!!!

# 前后端对接的思考及总结
## 说在前面的话
随着前端NodeJs技术的火爆,现在的前端已经非以前传统意义上的前端了,各种前端框架(Vue、React、Angular......)井喷式发展,配合NodeJs服务端渲染引擎,目前前端能完成的工作不仅仅局限于CSS,JS等方面,很多系统的业务逻辑都可以放在前端来完成,例如我司的**管控**
那可能有些人会说,前端这么火,NodeJs发展这么迅猛,后端是不是以后都没事情干了,其实不然,拿Java来说,经过这么多年发展,已经相当稳定,完善的生态圈也非最近今年发展起来的NodeJs可比,我们常常说**闻道有先后,术业有专攻**,用在这里最合适不过了,**集群**、**分布式**、**高可用**等等技术还是需要后端架构师来思考的事情
目前前端同后端的合作方式是前后端分离,通过Nginx+Tomcat的组合部署(还可加nodejs中间件)方式能有效的进行解耦,并且前后端分离为项目以后的架构扩展、微服务化、组件化都打下重要基础,所以这在以后是一个发展的必然趋势,我们需要去适应,做出改变!!!
## 早期的开发方式
早期的开发方式如下图:
![s1](s1.png)
这也是我前面工作1-3年的开发方式,我们没有前端帮我们写JS函数功能,所有的页面表单验证,数据渲染,数据接口编写都是我们后端全部实现,看上去更像是一个全栈工程师,从需求分析、搭建整个技术架构、数据库表设计、功能设计、编码开发,再到最终部署上线,我们无所不在,这可能也是目前很多小公司仍然在沿用的开发方式,很多后端同学担负起了项目的方方面面
以我目前的经验来看,这样的开发方式对我个人的成长是有益无害的,因为你只有在了解了前端的JS/CSS/HTML的情况下,然后再谈目前的前后端分离,会让你的工作事半功倍,在写后端接口前,你脑子里浮现的是整个功能的交互页面,最终呈现的是前后端合作开发好后的的终端结果,这大大缩减了前后端的沟通交流
## 前后端分离的探索
### jsonp
可能由于我在前面三年积累了丰富的前端经验,在上家公司主要负责开发官网、微信、后台等相关系统的接口,前期我们的开发方式虽然也是前后端分离的方式,但大都使用jsonp跨域接口调用的方式来达到分离效果,后端所有的接口都是可跨域调用的jsonp形式,抛开需要登录的授权之外的接口,前端在开发的时候本地无需开启服务即可调用服务端接口,然后渲染数据,完成页面交互渲染效果
jsonp的优点
> 不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制>> 兼容性更好,在更低版本的ie浏览器中都能兼容,这里区别于cors跨域类型
jsonp的原理其实很简单,当然,这也涉及到前端的知识,简单点说就是js端的function函数执行
正常的后端响应数据,例如:
```json{    "code":"8200",    "data":{        "id":"100",        "name":"Test"        //more......    }}```
jsonp需要的返回格式:
```jsoncallback({    "code":"8200",    "data":{        "id":"100",        "name":"Test"        //more......    }});```
前端在页面定义callback回调函数,callback函数接收后端响应回来的data-json数据,后端响应后执行callback函数达到调用前端业务逻辑的目的,渲染页面
### nginx+ajax
这种配合开发方式也是适合前端还没有引入Node等一站式开发解决方案的情况下引入的,纯粹的HTML+CSS+JS同后端对接,绑定业务接口,渲染数据
我们在使用JSONP开发的时候,前端都是需要在页面端写死HOST+IP接口地址,存在很重大一个弊端就是前端需要些config文件,来配置我们后端的接口请求地址,如果前端工程师规范意识强一点,会通用到一个配置文件里,但是如果没有这方面的意识的话,就会出现代码里硬编码的情况,不利于服务器迁移,代码更新,接口变动等操作
为规避上面碰到的问题,使用nginx的反向代理功能,将后端服务器代理下来,前端在开发的时候本地开启nginx服务,即解决了jsonp跨域问题,同时也解决了无需写死后端的服务ip+端口地址,利于后端在部署时整合代码,减少不必要的错误
### node
随着NodeJs的火热,前端已经可以本地开启服务写接口的情况下,就类似服务端开启tomcat一样,在这样的情况下,前端框架VUE、React等都在此基础上,提供了一套完整的技术解决方案,这和上面说到的开启nginx服务架构有点类似
这样做的意义:真正的解放了前后端,专注各自擅长的领域
技术架构如下:
![](jg.png)
前端node服务直接访问后端Java Restful Api接口服务,Api接口最终访问数据库完成数据查询最终返回node层,node渲染响应数据到前端
如果存在会话信息同步等问题,可以使用中间件,例如redis缓存数据库,解决前端node和后端Api信息同步问题,传参可以通过**JWT**等方式完成接口权限验证
不管是jsonp还是ajax+nginx这两种方式,node作为中间件都可以轻松切换处理,而且node作为中间层,还可以将多个后端接口组合成一整个数据集,最终以同步的方式渲染前端,这也利于做SEO优化,也是前面两种方式无法做到的
关于前后端分离,详细可阅读[前后端分离的思考与实践](http://blog.jobbole.com/65513/?from=timeline&isappinstalled=0),该文章详细的列述了关于前后端分离的实际经验
## 谈谈接口
随着前后端的分离,后端工程师不需要编写页面,不需要写JS,只需要提供接口即可,可是就是仅仅这一个接口,对于很多后端开发工程师而言,在实际开发,同前端对接的过程中,依然问题重重
很多后端同学说我只负责写接口,其他我一概不管,这样造成的后果就是
**1、接口结构无序、杂乱无章**
**2、接口和实际业务场景不相匹配、不可用**
**3、频繁的同前端沟通,简单的事情复杂化,前后端都很恼火**
**4、事情没做好**
后端在编写接口前,首先是对业务的理解,在对业务未理解透彻之前,编码都是无意义的,作为后端来说,需要锻炼自己对整个系统全局考虑的能力,接口之间并非是毫无关联的,我们在写第一个接口之间,其他接口之间的业务逻辑也许考虑到,这在后端团队合作开发不同功能的情况下显得尤为重要.
后端在开发接口时,我觉得主要从以下几个方面需要注意:
> 接口url 定义>> 接口类型、参数>> 全局错误码定义>> 接口json格式>> 接口文档编写
### 接口url定义
对于后端开发人员来说,接口前端入参,最终组合查询数据库资源,经过一系列相关业务场景下的计算,响应给前端json数据,每一层url的path定义需要清晰明了,这和后端在使用AOP定义事务管理同理,后端service需要满足一定的命名规范,这样方便统一管理,而且有这层规范后,后续的前后端对接会轻松很多
为了在许多API和长时间内提供一致的开发人员体验,API使用的所有名称应为:
- 简单- 直觉- 一致
这包括接口,资源,集合,方法和消息的名称。
由于许多开发人员不是英文母语人士,因此这些命名约定的目标之一是确保大多数开发人员能够轻松了解API。 它通过鼓励在命名方法和资源时使用简单,一致和小的词汇表来实现。
- API中使用的名称应该是正确的美国英语。例如,许可证(而不是许可证),颜色(而不是颜色)。- 可以简单地使用常用的简短形式或长字的缩写。例如,API优于应用程序编程接口。- 尽可能使用直观,熟悉的术语。例如,当描述删除(和销毁)资源时,删除是优先于擦除。- 对同一概念使用相同的名称或术语,包括跨API共享的概念。- 避免名称重载。为不同的概念使用不同的名称。- 仔细考虑使用可能与常用编程语言中的关键字冲突的名称。可以使用这些名称,但在API审查期间可能会触发额外的审查。谨慎和谨慎地使用它们。
### 接口类型、参数
关于接口的请求类型,目前比较常用的:`GET`、`POST`、`PUT`、`DELETE`、`PATCH`
> GET(SELECT):从服务器取出资源(一项或多项)。>> POST(CREATE):在服务器新建一个资源。>> PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)。>> PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)。>> DELETE(DELETE):从服务器删除资源。
后端可根据不同的业务场景定义不同的接口类型
在定义接口参数之时,目前我们常用的几种提交方式
**表单提交,application/x-www-form-urlencoded**
![](req.png)
表单提交主要针对`key-value`的提交形式
如下Java片段:
```java@PostMapping("/queryAll")public RestfulMessage queryAll(RuleCheckLogs ruleCheckLogs, @RequestParam(value = "current_page",defaultValue = "1")Integer current_page            , @RequestParam(value = "page_size",defaultValue = "10")Integer page_size            , @RequestParam(value = "tableName",required = false) String tableName){        RestfulMessage restfulMessage=new RestfulMessage();        try{            assertArgumentNotEmpty(ruleCheckLogs.getProjectId(),"质检方案id不能为空"); restfulMessage.setData(qcRuleCheckLogsService.queryRuleLogsByPage(ruleCheckLogs,tableName,current_page,page_size));        }catch (Exception e){            restfulMessage=wrapperException(e);        }        return restfulMessage;}```


**文件流提交**
**json提交,application/json**
![](req1.png)
json提交方式在SpringMVC或Spring Boot中主要有两种,一种是以`@RequestBody`注解接收方式,另外一种是以`HttpEntity<String> requestEntity`字节接收
Java代码示例:
```java@PostMapping("/mergeModelEntitys")public RestfulMessage mergeModelEntitys(HttpEntity<String> requestEntity){    RestfulMessage restfulMessage=new RestfulMessage();    try{        JsonObject paramsJson = paramJson(requestEntity);        assertJsonNotEmpty(paramsJson,"请求参数不能为空");        //more...    }catch (Exception e){        restfulMessage=wrapperException(e);    }    return restfulMessage;}```
### 全局错误码定义
错误码的定义同HTTP请求状态码一样,对接者能通过系统定义的错误码,快速了解接口返回错误信息,方便排查错误原因
```java{    "code": "8200",    "message": "Success",    "data": {        "total_page": 1,        "current_page": 1,        "page_size": 10,        "count": 5,        "data": [            {                "id": "a29ab07f1d374c22a72e884d4e822b29",                //......            }//....        ]    }}```
### 接口json格式
后端响应json给前端需要注意以下几点:
**1、json格式需固定**
例如如下图形
![](tb.png)
如上图所示,横向是时间,纵向是value值
我们给出的json结构应该如此:
```json[    {        "date":"2018-01",        "value":100    },    {        "date":"2018-02",        "value":200    }    //more...]```
在工作中,我们经常碰见这样的数据格式:
```json[    "2018-01":{    value:100    },    "2018-02":{    value:200    }    //more...]```
这里所说的json格式固定主要针对此种情况,后端给到前端的接口格式必须是固定的,所有动态数据值都需相应的key与之对应
**2、所有返回接口数据需直接可用,越简单越好**
后端提供给前端的接口数据,最终交给前端的工作,只需要让前端渲染数据即可,越简单越好,不因掺杂过多的业务逻辑让前端处理,所有复杂的业务逻辑,能合并规避掉的都需后端处理掉.
### 接口文档编写
接口文档编写是前后端对接重要依据,后端写明接口文档,前端根据接口文档对接
文档形势目前主要分几种:
1、依赖swagger框架,自动生成接口文档(swagger只能生成基于key-value详细参数方式,针对json格式,无法说明具体请求内容)
2、手动编写说明文档,推荐markdown编写
## 接口对接
万事俱备,只欠东风,虽然上面我们准备了所有我们该准备的,接口定义完美无缺,接口文档也已说明,但在对接时任然可能出现问题,此时我想我们还需注意的细节
**1、后端接口需自行进行Junit单元测试**
Spring目前集成Junit框架可方便进行单元测试,包括对业务bean的方法测试,以及针对api的mock测试
```java@RunWith(SpringRunner.class)@SpringBootTestpublic class QcWebApplicationTests {
@Autowiredprivate WebApplicationContext context;
private MockMvc mvc;
@AutowiredQcFieldService qcFieldService;
@Beforepublic void setUp() throws Exception {        //初始化mock对象mvc = MockMvcBuilders.webAppContextSetup(context).build();}
@Testpublic void queryByDsId(){try {            //针对mock-接口Controller层测试mvc.perform(MockMvcRequestBuilders.post("/qc/entity/queryByDsId")                    .contentType(MediaType.APPLICATION_JSON_UTF8)                    .param("dsId", "7d4c101498c742368ef7232f492b95bc")                    .accept(MediaType.APPLICATION_JSON))                    .andExpect(MockMvcResultMatchers.status().isOk())                    .andDo(MockMvcResultHandlers.print());} catch (Exception e) {e.printStackTrace();}}        @Test    public void testUpdateField(){QcField qcField=new QcField();qcField.setId("513ee55f5dc2498cb69b14b558bc73e6");qcField.setShortName("密码");        //业务bean-service方法测试qcFieldService.updateBatchFields(Lists.newArrayList(qcField));}```
**2、使用工具测试,推荐PostMan**
作为接口调试神器,Postman大名想必大家都已知道
作为后端来说,我们需要学会查看chrome推荐给我们的审查元素的功能,可参看[Chrome开发工具介绍](https://segmentfault.com/a/1190000000683599)
chrome提供了一个可以copy当前接口的url功能,最终生成curl命令行
![](copy.png)
最终通过`Copy as cURL(bash)`功能可生成curl命令
```javacurl 'http://demo.com/qc/ds/getAll' -H 'Origin: http://demo.com' -H 'Accept-Encoding: gzip, deflate' -H 'Accept-Language: zh-CN,zh;q=0.9' -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36' -H 'Content-Type: application/x-www-form-urlencoded' -H 'Accept: application/json, text/plain, */*' -H 'Referer: http://demo.com/index.html' -H 'Connection: keep-alive' --data 'current_page=1&page_size=6&' --compressed```
以上命令可以在Linux等各终端直接执行
**curl命令**是一个利用URL规则在命令行下工作的文件传输工具。它支持文件的上传和下载,所以是综合传输工具,但按传统,习惯称curl为下载工具。作为一款强力工具,curl支持包括HTTP、HTTPS、[ftp](http://man.linuxde.net/ftp)等众多协议,还支持POST、cookies、认证、从指定偏移处下载部分文件、用户代理字符串、限速、文件大小、进度条等特征。做网页处理流程和数据检索自动化,curl可以祝一臂之力。
postman提供导入curl命令行
![](im.png)
**3、前后端需心平气和沟通,勿推卸责任,前后端开发人员水平不尽相同,作为同事,需要的是团结合作,努力将事情做好,而非相互推卸**
## 结语
前后端分离,简化了我们的开发方式,不同人专注于不同的领域,技术价值最大化,大大提高工作效率,我们在掌握这些技能的同时,也需要加强自身的发展,以适应当前的技术发展趋势,不管是前端还是后端,多了解一些,总是没错的,古人云:**技多不压身**,我想也正是此理!!!

猜你喜欢

转载自www.cnblogs.com/xiaoymin/p/8906585.html
今日推荐