当前位置: 首页 > Web前端 > HTML

前后端对接的思考与总结

时间:2023-04-02 20:42:27 HTML

随着前端NodeJs技术的流行,现在的前端已经不再是传统意义上的前端,各种前端框架(Vue,React,Angular...)井喷式开发,配合NodeJs服务端渲染引擎,前端可以完成的工作不局限于CSS、JS等,很多系统的业务逻辑都可以在前端完成。目前,前端与后端的协作是前后端分离。通过Nginx+Tomcat的组合部署(也可以加入nodejs中间件)可以有效的进行解耦,前后端分离,为以后的架构扩展,微服务,组件化奠定了基础一个重要的基础,所以这是未来发展的必然趋势,我们需要适应和改变!!!早期的开发方式早期的开发方式如下图所示:探索前后端分离。JSONp可能是我前三年积累的丰富的前端经验所致。在之前的公司,我主要负责官网、微信、后台系统的界面开发。虽然我们的开发方式也是前后端分离的方式,但是大多都是通过jsonp跨域接口调用的方式来达到分离的效果。所有后端接口都是jsonp形式,可以跨域调用,除了登录授权。接口,前端在开发时可以在不开启服务的情况下在本地调用服务端接口,然后渲染数据完成页面的交互渲染效果。jsonp的优点是不像XMLHttpRequest对象实现的Ajax请求那样受同源策略的限制,兼容性更好,可以兼容低版本的IE浏览器。这里区别于CORS跨域类型jsonp的原理其实很简单。当然,这也涉及到前端知识。简单的说就是js端的function函数正常执行。结束响应数据,例如:{"code":"8200","data":{"id":"100","name":"Test"//more...}}JSONP需要返回格式:回调({“代码”:“8200”,“数据”:{“id”:“100”,“名称”:“测试”//更多......}});前端在页面上定义了callback回调函数,回调函数接收后端响应返回的data-json数据,在后端响应后执行回调函数,达到调用前端业务逻辑的目的。用nginx+ajax渲染页面同样适用于前端开发,无需引入Node等,在一站式开发方案的情况下引入,纯HTML+CSS+JS对接后端,绑定业务接口,渲染data当我们使用JSONP进行开发时,前端需要在页面端硬编码HOST+IP接口地址,这是一个非常严重的劣势。前端需要一些配置文件来配置我们后端的接口请求地址。如果前端工程师规范意识比较强,会在一个配置文件中使用,但是如果没有这方面的意识,代码中就会出现硬编码,不利于服务器迁移,代码更新,为了避免上面遇到的问题,界面变化等操作使用了nginx的反向代理功能来代理后端服务器。前端在开发时在本地开启nginx服务,解决了jsonp跨域问题,也解决了不需要记下后端服务ip+端口地址的问题,有利于后端在开发过程中整合代码部署并减少不必要的错误在这种情况下,前端框架VUE、React等在此基础上提供了一套完整的技术解决方案,这与上述开放nginx服务架构有些相似。技术架构如下:前端节点服务直接访问后端JavaRestfulApi接口服务,Api接口最终访问数据库完成数据查询,最后返回节点层,节点渲染响应数据给前端如果存在session信息同步等问题,可以使用中间件,比如redis缓存数据库,解决前端节点和后端Api信息同步的问题,传参即可通过JWT等方式完成接口权限校验,无论是jsonp还是ajax+nginx,node作为中间件可以方便的切换处理,node作为中间层也可以将多个后端接口组合成一个完整的数据集,最后同步渲染前端,这样也有利于SEO优化,这也是前面两种方式做不到的。前后端分离,可以详细阅读前后端分离的思考与实践。本文详细列举了前后端分离的实际经验,并谈了谈接口。前后端分离,后端工程师不用写页面,不用写JS,你只需要提供一个接口,但也只是这个接口。对于很多后端开发工程师来说,在实际开发和前端对接的过程中,还是会遇到很多问题。很多后端同学说我只负责写接口,其他的我根本不管,这样的后果是1.接口结构混乱,没有条理2.接口不匹配实际业务场景,不可用3、频繁和前端沟通,把简单的事情搞复杂了,前后端都很烦4、事情没做好。在写接口之前,后台首先要了解业务。在业务没有搞清楚之前,编码是没有意义的。作为后端,需要发挥其对系统整体的考虑能力。,接口不无关系。我们可以考虑第一个接口和其他接口之间的业务逻辑。当后端团队合作开发不同的功能时,这一点尤为重要。后端在开发接口的时候,我觉得需要注意以下几个方面:接口url定义接口类型,参数全局错误码定义接口jsOnformat接口文档编写接口url定义供后端开发者,接口前端输入参数,最后结合查询数据库资源,在相关业务场景经过一系列计算,响应前端json数据,路径各层url的定义需要清晰明了。这和后端使用AOP定义事务管理是一样的。后端服务需要满足一定的命名规范,便于统一管理。而且有了这个级别的规范,后续的前后端对接也会容易很多。为了为API和随着时间的推移提供一致的开发人员体验,API使用的所有名称都应该:简单、直观和一致这包括接口、资源、集合、方法和消息的名称因为许多开发人员的母语不是英文,这些命名约定的目标之一是确保大多数开发人员可以轻松理解API。它通过鼓励在命名方法和资源时使用简单、一致和小的词汇表来做到这一点。API中使用的名称应该是正确的美国英语。例如license(而不是license)、color(而不是color)。您可以简单地使用常用的短形式或长词的缩写。例如,API优于应用程序编程接口。尽可能使用直观、熟悉的术语。例如,在描述资源的删除(和销毁)时,删除优先于擦除。对同一概念使用相同的名称或术语,包括跨API共享的概念。避免名称重载。对不同的概念使用不同的名称。仔细考虑使用可能与常见编程语言中的关键字冲突的名称。可以使用这些名称,但可能会在API审查期间触发额外的审查。谨慎而明智地使用它们。接口类型及参数关于接口的请求类型,目前比较常用的有:GET、POST、PUT、DELETE、PATCHGET(SELECT):从服务器获取资源(一项或多项)。POST(CREATE):在服务器上创建一个新的资源。PUT(UPDATE):更新服务器上的资源(客户端提供改变后的完整资源)。PATCH(UPDATE):更新服务器上的资源(客户端提供更改的属性)。删除(DELETE):从服务器中删除一个资源。后台可以根据不同的业务场景定义不同的接口类型。在定义接口参数时,目前有几种我们常用的提交方式。表单提交,application/x-www-form-urlencoded表单提交主要针对key-value提交表单下面Java片段:@PostMapping("/queryAll")publicRestfulMessagequeryAll(RuleCheckLogsruleCheckLogs,@RequestParam(value="current_page",defaultValue="1")Integercurrent_page,@RequestParam(value="page_size",defaultValue="10")Integerpage_size,@RequestParam(value="tableName",required=false)StringtableName){RestfulMessagerestfulMessage=newRestfulMessage();try{assertArgumentNotEmpty(ruleCheckLogs.getProjectId(),"质检方案id不能为空");restfulMessage.setData(qcRuleCheckLogsService.queryRuleLogsByPage(ruleCheckLogs,tableName,current_page,page_size));}catch(Exceptione){restfulMessage=wrapperException(e);}returnrestfulMessage;}文件流提交json提交,application/jsonjson提交方式在SpringMVC或者SpringBoot中主要有两种,一种是通过@RequestBody注解接收,一种是通过HttpEntity<接收Java代码示例String>requestEntity字节:@PostMapping("/mergeModelEntitys")publicRestfulMessagemergeModelEntitys(HttpEntityrequestEntity){RestfulMessagerestfulMessage=newRestfulMessage();尝试{JsonObjectparamsJson=paramJson(requestEntity);assertJsonNotEmpty(paramsJson,"请求参数不能为空");//更多...}catch(Exceptione){restfulMessage=wrapperException(e);}returnrestfulMessage;}在SpringMVC或者SpringBoot中提交json的方式主要有两种,一种是使用@RequestBody注解接收,另一种是使用HttpEntityrequestEntity部分接收Java代码示例:@PostMapping("/mergeModelEntitys")publicRestfulMessagemergeModelEntitys(HttpEntityrequestEntity){RestfulMessagerestfulMessage=newRestfulMessage();尝试{JsonObjectparamsJson=paramJson(requestEntity);assertJsonNotEmpty("参数不能为空");//更多...}catch(Exceptione){restfulMessage=wrapperException(e);}returnrestfulMessage;}全局错误码的定义错误码的定义与HTTP请求状态码相同,docker可以通过系统定义的错误码快速了解接口返回的错误信息,以及方便排查错误原因{"code":"8200","message":"Success","data":{"total_page":1,"current_page":1,"page_size":10,“计数”:5,“数据”:[{“id”:“a29ab07f1d374c22a72e884d4e822b29",//...}//....]}}接口为json格式后端以json响应给前端,需要注意以下几点:1.json格式需要固定。对于例子,下图就是上图,横的是时间,竖的是值我们给的json结构应该是这样的:[{"date":"2018-01","value":100},{"date":"2018-02","value":200}//more...]在工作中,我们经常会遇到这样的数据格式:["2018-01":{value:100},"2018-02":{value:200}//more..]这里说的固定json格式主要是针对这种情况的,后端到前端的接口格式必须是固定的,所有的动态数据值都需要对应到2.所有返回的接口数据必须是直接可用的,越简单越好,后端提供给前端的接口数据,最后交给前端,只需要让前端渲染即可数据,硅越简单越好,不要因为业务逻辑太多而让前端处理,所有复杂的业务逻辑都可以合并,避免需要后端处理。接口文档编写接口文档编写是前后端对接的重要基础。.依赖swagger框架自动生成接口文档(swagger只能根据key-value生成详细参数,对于json格式无法解释具体的请求内容)2.手动写描述文档,推荐markdown写接口对接一切都是准备好了,只欠东风,虽然上面该准备的东西我们都准备好了,接口定义很完善,接口文档也有说明,但是在对接的时候还是有可能会出现问题。这个时候我觉得还是需要注意细节1.后端接口需要自己进行Junit单元测试Spring目前集成了Junit框架方便进行单元测试,包括对业务bean的方法测试和对业务bean的mock测试api@RunWith(SpringRunner.class)@SpringBootTestpublicclassQcWebApplicationTests{@AutowiredprivateWebApplicationContext上下文;私有MockMvcmvc;@AutowiredQcFieldServ冰qcFieldService;@BeforepublicvoidsetUp()throwsException{//初始化模拟对象mvc=MockMvcBuilders.webAppContextSetup(context).build();}@TestpublicvoidqueryByDsId(){try{//模拟接口控制器层测试mvc.perform(MockMvcRequestBuilders.post("/qc/entity/queryByDsId").contentType(MediaType.APPLICATION_JSON_UTF8).param("dsId","7d4c101498c742368ef7232f492b95bc").accept(MediaType.APPMultvExpRes))ockockstatersstat().isOk()).andDo(MockMvcResultHandlers.print());}catch(Exceptione){e.printStackTrace();}}@TestpublicvoidtestUpdateField(){QcFieldqcField=newQcField();qc字段。setId("513ee55f5dc2498cb69b14b558bc73e6");qcField.setShortName("密码");//业务bean-service方法测试qcFieldService.updateBatchFields(Lists.newArrayList(qcField));}2.使用工具进行测试,推荐PostMan作为界面调试神器,Postman的大名想必大家都耳熟能详。作为后台,我们需要学习查看chrome推荐的review元素的功能。见铬开发工具介绍Chrome提供了一个url功能,可以复制当前界面,最后生成一个curl命令行,最后通过Copy生成一个curl命令curl'http://demo.com/qc/ds/getAll'作为cURL(bash)函数-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(WindowsNT10.0;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/65.0.3325.181Safari/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&'--compressedabove命令可以在linux等终端直接执行。curl命令是一个使用URL规则在命令行下工作的文件传输工具。它支持文件上传和下载,所以是一个综合性的传输工具,但是按照传统,习惯上称curl为下载工具。作为一个强大的工具,curl支持包括HTTP、HTTPS、ftp等多种协议,还支持POST、cookies、身份验证、从指定偏移量下载部分文件、用户代理字符串、速度限制、文件大小、进度条等功能,ETC。。要自动化网页处理和数据检索,curl可以提供帮助。postman提供importcurl命令行