点击上方“朱小厮的博客”,选择“设为星标”

做积极的人,而不是积极废人!

本文来自

https://juejin.im/post/59eafab36fb9a045076eccc3

前言

随着互联网高速发展,公司对项目开发周期不断缩短,我们面对各种需求,使用原有对接方式,各端已经很难快速应对各种需求,更难以提高效率。于是,我们不得不重新制定对接规范、开发逻辑以便快速上线项目。

我们的目标

  1. 尽可能的缩小沟通的成本,开最少的会,确定大部分的事。

  2. 花最少的时间写文档,保证90%的开发人员看懂所有内容。

  3. 哪怕不看文档,也能知道各种接口逻辑。

  4. 不重复写代码

  5. 尽可能的写高可读性的代码

我们做了哪些事

  1. 完成了前后端分离

  2. Android、ios、web共用一套接口

  3. 统一接口规范(post、put、get、patch、delete)

  4. 统一了调试工具

  5. 统一了接口文档

之前的我们

接口是这样子的:

接口地址 含义 请求方式
…/A项目/模块1/getProducts 获得产品 GET
…/A项目/模块1/addProduct 添加产品 POST
…/A项目/模块1/getProductDetail 获得产品详情 GET
…/A项目/模块1/editProduct 修改产品 POST

客户端请求是这样的:

  • …/A项目/模块1/getProducts?id=1&a=2&b=3&c=4&d=5…………

  • A页面=====》B页面(携带n个变量)====》C页面(携带m个变量,包含i个A页面的变量) -------经常n>4

  • 大部分请求是POST,至于put、patch、delete是什么鬼,关我屁事。

  • 关于接口入参使用json,那完全是看开发心情。

出参是这样的:

{"message":"success","code":0,"data":具体内容}
其中data里包含数组可能是
[{"a":"1","b":"1"},{"a":"1","b":"1"},{"a":"1","b":"1"},{"a":"1","b":"1"}]
即使下一个页面用到也不会使用id,而是把所有字段都传进去。
A接口中,返回产品用product;B接口中使用good,多个接口很可能不统一。

客户端对接是这样子的:

  • 安卓、ios一套;部分接口各自用一套;html5端一套。

  • 客户端和后台是不停交流的

接口文档是这样的

img

img
  1. swagger

  2. 阿里的rap

  3. Word文档

  4. 其它

当然了,我觉得swagger和rap神器都是非常强大的,能够实现各种功能逻辑,但是考虑到开发人员掌握程度不通,复杂度较高,难以提高效率,我决定初期并不使用这两样神器。

后端是这样的

…/A项目/模块1/getProducts ----接口
…/A项目/模块1/Products.html ----页面
…/A项目/模块1/Products.js ----静态资源

接口和静态资源缠在一块,毕竟很多页面可能是一位开发人员同时开发前端、后端,这里的弊端是,只需要自己清楚逻辑,很多做法临时应付,方案并不优雅,别人也很难看懂。一旦这位同事离职,很多说不清的逻辑就留给后人采坑了。

等等…………

重构

下面步入正题,面对以上众多问题聊聊我是如何重新制定流程的

数据库约定

约定数据库里所有表必须包含名为id主键字段。
可能有人会说,正常来说不是每张表里都应该有id主键吗?但是,我们项目中由于之前开发不严谨,部分表没有id主键,或者不为id的主键。这里我们采用分布式的全球唯一码来作为id。

api出参约定

约定所有出参里含list,且其他请求会用到这组list,则list里所有对象必须含id唯一标识。

入参约定

约定token身份认证统一传入参数模式,后端采用aop切面编程识别用户身份。其他参数一律为json。

resultfull接口约定

首先我们选择一个名词复数,比如产品

post方法

新增一条XXX
比如 ……/products 则代表新增一条产品
入参json如下:

{    "name":"我是一款新产品",    "price":100,    "kind":"我的分类",    "pic":[一组图片],    等等还有很多

}

java 代码control层

    @ResponseBody    @RequestMapping(value = "/A项目/B模块/products", method = {RequestMethod.POST})    public ResultObject getProducts() {        //具体逻辑。    }

put方法

新增某条XXX记录
比如 ……/products/1111111111
入参json如下:

{    "name":"我是一款新产品",    "price":100,    "kind":"我的分类",    "pic":[一组图片],    等等还有很多

}

表示增加一条1111111111id的记录
java代码control层

    @ResponseBody    @RequestMapping(value = "/A项目/B模块/products/{id}", method = {RequestMethod.PUT})    public ResultObject putProducts(@PathVariable(value = "id") String id) {        //具体逻辑。    }

get方法

获得所有XXX
……/products 则代表获取所有产品
因为有分页,所以我们后面加了?page=1&pageSize=50

我们约定了所有名词复数,都会返回list,且list每个对象都有字段为id的唯一id。
比如

{    "data":{"list":[{"id":"唯一id","其他很多字段":""},{"id":"唯一id","其他很多字段":""}],"page":1,其他字段},    "code":0,    "message":"成功"}

……/products/{id} 获取某个具体产品(一定比列表更详细)

比如某个具体产品里还包含一个list,如该产品推荐列表,则:
……/products/{id}/recommendations

假设它包含的不是一个list,而是对象,比如产品佣金信息,则:
……/products/{id}/Commission

这里我们以是否名词复数来判断是对象还是list.

java代码control层

    @ResponseBody    @RequestMapping(value = "/A项目/B模块/products/{id}", method = {RequestMethod.GET})    public ResultObject putProducts(@PathVariable(value = "id") String id) {        //具体逻辑。    }

patch 方法

更新局部XXX产品YYY信息
入参是post方法时入参的子集,所有支持更新的参数会说明,并不是支持所有变量
……/products/{id}

{    "name":"我是一款新产品",    "price":100,    部分变量}

java代码control层

    @ResponseBody    @RequestMapping(value = "/A项目/B模块/products/{id}", method = {RequestMethod.PATCH})    public ResultObject putProducts(@PathVariable(value = "id") String id) {        //具体逻辑。    }

delete方法

删除XXX记录
……/products/11111

删除11111产品。
java代码control层

    @ResponseBody    @RequestMapping(value = "/A项目/B模块/products/{id}", method = {RequestMethod.DELETE})    public ResultObject putProducts(@PathVariable(value = "id") String id) {        //具体逻辑。    }

其他说明

我们尽可能少的使用动词,但有一些行为需要使用动词,比如登录等。
关于版本号,我们打算在模块后增加/v1/等标识。

权限约定

服务端要对用户角色进行判断,是否有权限执行某个逻辑。

前后端分离约定

后端以开发接口为主,不再参与页面开发,或者混合式jsp页面开发,统一以接口形式返回,前端通过js渲染数据以及处理逻辑。

共用接口

web、Android、ios使用统一接口,不在因为哪方特殊要求额外开放接口。

使用统一dao层生成工具

基于mybatis-generator改造成适合我们项目的dao层以及部分service层,内部共同维护共同使用。

使用postman最为接口文档、调试工具

虽然有上文中介绍的rap和swagger都是特别牛的接口神器,但是我们还是选择了postman,开发人员将接口名称、说明、入参、出参,以及各种出参示例都存储,这样开发直接可以看得清接口含义。

我们建议使用浏览器插件,这里以360极速浏览器为例。
插件下载地址:https://download.csdn.net/download/qq273681448/10033456

打开360浏览器扩展中心,然后勾选开发者模式,再点击加载已解压的扩展程序,选中压缩包解压后的目录,最后点击运行即可。

img

其中出参注释、及接口说明,写在tests里:

/*这里是接口说明,和每个出参、入参的意思。*/

img

接口按模块划分为文件夹:

img

入参:

img

出参示例:

img

正常请求:

img

开发人员即可直接看到接口示例进行开发,而开发人员开发的时候,自己调用一次即可保存为postman文件,为了加快上线,我们允许将java中实体类变量定义的代码(含注释)直接复制粘贴出来。

js等静态资源缓存问题

从短期角度上讲,我的要求是减少js文件的变更,如果有变更,务必更改版本号。那么如何减少修改,我们的做法是将一部分js写在html内,反正前后端分离,大不了刷新一下cdn的节点缓存,毕竟大部分浏览器也不会主动缓存html文件(大部分浏览器会缓存js等文件)。

统一js请求框架

这里我们使用angular js的请求框架,因为我们内部对angularjs使用较多,比较熟悉,封装后的请求,可以自动弹窗错误请求,可复写错误回调。

目前效果

目前,我们客户端看到接口,大概能说出其意思,也能猜出一连串接口的含义,比如
……/classes
可以看出它是获取班级列表接口,猜到

……/classes/id get获取id为id的班级详情
……/classes/id patch 修改班级信息
……/classes/id delete 删除班级信息

至于入参,patch是post的子集、put=patch、delete无入参。

而入参含义,直接打开postman可以直接查看每个字段的含义,并且,可以实时调取开发环境数据(非开发人员电脑),这里我们使用了多环境,详情可了解我之前写的一篇
我是如何重构整个研发项目,促进自动化运维DevOps的落地?

前端使用统一封装后的js请求框架也加快了开发进度,不用造轮子。

开发人员,一般代码开发写好,使用postman自我测试,测试完成后,接口文档也就写好了。

测试人员想了解接口文档的也可以直接使用postman进行导入查看。

至此,我们交流成本下降了一大半,剩下开会的内容就是按ui分解需求或者按ui施工了。

总结

经过一番的折腾,开发进度总算快了点,也一定程度上达到了快速上线项目的效果。关于restful风格api,每个人都有自己的见解,只要内部约定清楚,能尽可能少的减少沟通,我觉得就是好的理解。至于接口工具,可能很多人会说为什么不用之前的,我觉得以后还是会用的,最好能做到插件自动化生成api,但是对java开发注释要求比较严格,随意慢慢来吧,毕竟后面我们还有很多路要走。


往期精彩

《阿里大佬分享面试体会》

《Dubbo:9个你不一定知道但好用的功能》

《浅析Linux IO》

《FESCAR:阿里重磅开源分布式事务解决方案》

>>>加微信,进入群聊

喜欢就点一下「好看」呗~

android怎么截取接口返回html代码中的内容_某神秘公司 RESTful、共用接口、前后端分离、接口约定的实践...相关推荐

  1. android怎么截取接口返回html代码中的内容_如何实现文本内容折叠并显示“...查看全部”?...

    来源 | https://wintc.top/article/58多行文本超过指定行数隐藏超出部分并显示"...查看全部"是一个常遇到的需求,网上也有人实现过类似的功能,不过还是想 ...

  2. 前后端解析_好程序员Web前端教程分享前后端分离接口

    随着互联网的高速发展以及IT开发技术的升级,前后端分离已成为互联网项目开发的业界标准使用方式.在实际工作中,前后端的接口联调对接工作量占Web前端人员日常工作的30%-50%,甚至会更高.接下来的好程 ...

  3. 好程序员Web前端教程分享前后端分离接口

    随着互联网的高速发展以及IT开发技术的升级,前后端分离已成为互联网项目开发的业界标准使用方式.在实际工作中,前后端的接口联调对接工作量占Web前端人员日常工作的30%-50%,甚至会更高.接下来就给大 ...

  4. FastAPI + Vue 前后端分离 接口自动化测试工具 apiAutoTestWeb

    apiAutoTestWeb使用说明 apiAutoTestWeb 是为apiAutoTest的可视化版本,其采用前后端分离( FastAPI + Vue2 )方式实现 具体使用: Python3 + ...

  5. vue+node前后端分离接口调用(初学者)

    一.node编写接口 (设定你已使用Node+express搭建好了项目,可参照我的上一篇博客) 我们就在users.js下进行接口编写 router.get('/getUserInfo',funct ...

  6. 利用Postman工具测试若依前后端分离接口

    若依(前端分离版本)系统测试接口使用方法 若依(前端分离版本)系统测试接口说明(项目源码地址:RuoYi-Vue:

  7. SSM框架中的前后端分离

    认识前后端分离 在传统的web应用开发中,大多数的程序员会将浏览器作为前后端的分界线.将浏览器中为用户进行页面展示的部分称之为前端,而将运行在服务器,为前端提供业务逻辑和数据准备的所有代码统称为后端. ...

  8. Django的前后端分离以及Rest风格接口开发大全

    1.什么是前后端分离开发: 就是前后端工程师约定好数据交互接口,并行的进行开发和测试,后端只提供数据,不负责将数据渲染到页面上,前端通过HTTP请求获取数据并负责将数据渲染到页面上,这个工作是交给浏览 ...

  9. 阿里云视频上传视频获取进度条问题(使用session方案,获取进度一直为0的解决方案)补充:前后端分离项目中获取进度解决方案

    1.场景描述: 之前用阿里云上传视频,前端反应上传视频经常出现获取视频url失败问题.但是接口我测过很多遍都是没有问题的.后台这边提供了一个视频上传的接口返回一个videoId,还提供了一个根据vid ...

  10. 【最新】SSM框架中的前后端分离

    文章目录 1.认识前后端分离 2.分离的四个好处 3.利用Swagger UI来规范书写API文档 1.认识前后端分离 在传统的web应用开发中,大多数的程序员会将浏览器作为前后端的分界线.将浏览器中 ...

最新文章

  1. iOS高效开发必备的10款Objective-C类库
  2. [原创] debian 9.3 搭建Jira+Confluence+Bitbucket项目管理工具(三) -- 安装confluence 6.6.1
  3. cmake使用示例与整理总结
  4. C#LeetCode刷题之#283-移动零(Move Zeroes)
  5. 不会真的有人拿了上万甚至几十万在网络上赌博吧?
  6. 凸优化第五章对偶 5.2Lagrange对偶问题
  7. Scratch编程与科学结合-串联与并联
  8. 企业微信小程序开发流程
  9. 自主开发新媒体,湖南卫视封杀网络转播权
  10. hdu3987 Harry Potter and the Forbidden Forest 最小割边数
  11. 使用vue写一个计时器
  12. HDU - 1242
  13. (笔记)yolov5自适应anchors
  14. 1.初识Node.js
  15. 解决Django报错:SQLITE 3.8.3 OR LATER IS REQUIRED
  16. 在线免费网页工具 :转换视频为wmv格式 izyc.net
  17. linux终端命令大全
  18. DL4J实战之一:准备
  19. WPF 中DataGrid控件显示和设置数据
  20. 【智能家居远程控制系统】ESP8266连接阿里云(一)

热门文章

  1. Linux集群在银行信息化中的应用(2)
  2. 中秋佳节,献上笔试题一道,祝各位事业蒸蒸日上!
  3. Illustrator 教程,如何在 Illustrator 中变换图稿?
  4. InDesign教程,如何更改字体和字体大小?
  5. 在 Mac 上的 Keynote 讲演中如何更改共享演示文稿的设置?
  6. 如何使用 AirPlay 在 Mac 上使用 HomePod?
  7. git不同的平台配置不同的公钥秘钥(git配置多个公钥秘钥)(git不同的项目配置不同的公钥秘钥)
  8. Dash for mac(代码文档浏览器)v6.0.8
  9. mac快速电脑锁屏/睡眠方法
  10. 第八章指针实验成绩汇总