序幕: 痛苦的来源
情景1
这可能是个真实的前后端合作开发的故事——
【人物】前端:阿新;后端新人:小弟
阿新:接口怎么样了?
小弟:哦……(此处省略1000字的实现细节)
阿新:我的意思是接口的参数,返回的数据格式这些定下来了么?
小弟:我都行啊, 看前端有什么需要。
……
此处省去几个回合来来回回&……&%……
终于各自回去开发说都完成了,来联调吧!
为了能各自在本地调试,又折腾了半天跨域访问需要的东西。
阿新:你没有看过之前的代码么?就算错了也要回200, 错误的信息放到json的一个字段里面..bla, bla
小弟:这还不简单, 我改一下就好了~
修改了几个回合后又报错了。
阿新:好吧,这次确实是我前端参数拼错了。
小弟:囧
终于功能联调通过,放到一起部署到服务器上后——
又,报,错,了……
情景2
私有化部署需要调试客户部署的机器的时候,部署的环境并不会部署调试工具, 当你做好最后无奈只能一边查curl文档一边敲命令的心理准备的时候,你发现curl命令还没有装。然而客户的内网机器不允许外网……
续章: 解脱之法
这些问题说到底只是http协议本身,前、端后开发人员三者之间确实存在巨大的鸿沟,导致沟通成本巨大,。这里就需要我好好地来润滑一下了。我采取的方法是:约定好最常使用的一个公司范围内最小语义子集充当润滑剂,即API文档化。
API文档,前后端并行开发
需求进来之后,前后端双方沟通之后约定接口,并提供api文档化,api文档单独进行版本管理,与之产品的设计原型版本大致同步(不一致的情况只有必须调整接口的技术重构),然后前后端并行开发。
调试
如果说api文档来驱动开发很理想化,那么根据api文档生成同一份请求和返回的mock server则为这种开发流程牢牢的扎稳了脚跟。
这里我们实现的mock server不仅仅是常见的接个请求然后返回一个写死http报文,而是说同样能够识别我们的文档,生成对应格式的请求和返回http报文,是否随机、还是指定特定的值,用来做错误或者正确的功能测试都没有任何问题。
到此不仅是前后端的人了解了api,前后端的代码也真正的识别了api,在抛开了前后端工程师思想上沟壑之后,当我们的注意力都能聚焦在真正的bug上的时候,我都不敢想象这幅美景,太美了~(事实上,不需要前后端共同开发联调靠喊,确实省了很多心)。
售后
部署的环境并没有趁手的工具的问题,加之如果是远程连接的话,一般都会很慢,这种情况下调试无疑是低效且痛苦的。为了解决在原始环境下调试的问题,我们将swagger-ui的静态页面跟随产品发布,并且各个部件提供了与之兼容的API的文档,能够在网页上读取API文档直接调试API。
我们现在考虑将swagger-ui的界面提供给售后、实施的同事,甚至客户来操作,抛开命令行,通过页面配置参数的方式来调试api接口发现问题,就不需要每次叫研发来确定发现问题了,而是直接通过售后的具体的api访问的返回来直接确定问题,然后解决了。
终章: 实现
谈完了YY的理想,我们来看看怎么将这些东西一步步落地到现实。
API标准: https://github.com/OAI/OpenAP... ,因为业务场景没有特定到有成熟的restful api的标准,所以我们选择了尽量通用且工具齐备的OpenAPI。
1、从代码中提取api文档,提供整套后端的api文档给swagger-ui的页面
▶ Java: jetty有一个现成的插件,能够很方便的从代码中生成api的文档。
▶ Python:因为Python的动态语言属性,不能直接效仿java的玩法,所以我给tornado做了一层类似django的中间件的内部python库出来, 在application实例上挂上两个api接口, 来提供api版本、和完整的api文档。
api版本接口是用来检查前后端之间是否说的是同一版本的api,尽量在越早的时间点发现错误。python提供api文档的方式是通过解析注册到application实例上所有路由对应的视图函数(或者说请求处理函数)中的_doc_来实现的,动态生成的方式免去了修改之后多余的生成步骤。
2、识别api文档的mock server
这里是前端自己用nodejs撸了一个识别OpenAPI的mock server, 将OpenAPI文档转换到http报文做了这么一层转换, 并在api的版本管理基础上,将各个版本的api文档做了可视化的展示,方便的生成对应的请求、返回http报文来测试功能、错误返回的检查,调试结束之后,改一下api所在的ip地址就可以无缝迁移成生产状态,so easy~
3、swagger-ui的定制
▶ token的验证;兼容原始的登陆cookies方式,如果在非登陆的浏览器里面访问,需要先从login接口拿到token,或者登陆获取cookies,因为就算是客户内网,各个部件之间的访问安全也是我们关心的,下一步就是说跟客户的认证系统挂钩,而不是走自己单独的一套认证。
▶ 编辑header,http报文; 用swagger-ui的静态页面就是为了能够省去操作命令行、依赖命令行命令的弊端,但是原生的swagger-ui并不支持修改请求的http报文,为此我们做了一些定制化的开发。
▶ 一些易用性的定制化,,比如: 支持多个同名查询参数。
END & NO END
到此,我们就搭建了一个由api文档串联起来的整个开发、测试、售后的完整流程。
文章到这就结束了, 但是我们要做的事还远未完结,我们才刚刚起航,你问我们的终点是何处?星辰大海?不,你的目标由你自己决定,你不来掺合一脚,怎么知道下一节的篇章不是你的署名?怎么知道你的终点岂止是星辰大海。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。