【效率专精系列】善用API统一描述语言提升RestAPI开发效率

团队内部RestAPI开发采用设计驱动开发的模式,即使用API设计文档解耦前端和后端的开发过程,双方只在联调与测试时耦合。在实际开发和与前端合作的过程中,受限于众多因素的影响,开发效率还有进一步提高的空间。本文的目的是优化工具链支持,减少一部分重复和枯燥的劳动。

现状梳理

前后端工作流

  1. 需求理解:前后端先理解产品思路、需求的详细内容
  2. 敲定接口:后端出API设计文档初稿,与前端面对面或者在线讨论修正,接着后端(有时是前端)把API描述记录到公司内部的API文档库(在线markdown编辑器,提供分级目录的存储功能,对如何描述API没有一定的标准,因此描述格式不统一,因人而异1)。接着根据双方工作的安排,约定联调时间
  3. 独立开发:双方独立开发(也有可能非完全独立开发,如需要对方的环境配合等;或者存在返工,如API设计发生变更等)
  4. 系统联调:测试API基本功能和双方系统的连通性
  5. 测试回归:开发或者QA编写测试用例并测试业务流程

可优化方向

1. 减少文档编写时间

根据个人的开发经验,后端编写API设计文档时常见的情况有:如果是简单的需求,API数量较少,后端直接通过内部即时通信软件和前端沟通;如果是复杂的需求,API数量较多,后端会先把API描述写到本地临时文档(纯文本、markdown、evernote等)或者内网(内部个人Wiki、git仓库)中,然后把链接发给前端review或者直接面对面沟通。这样的方式灵活,但存在一些问题,比如:

  • 描述格式没有标准。对于简单的描述,文档格式比较随意,双方基于约定和经验理解和开发1;完备的描述,编写文档所需时间较长,并且细节复杂(需要考虑不同的HTTP请求类型、HTTP头部信息、HTTP请求内容等),高质量地创建这份文档本身就是件非常吃力的事,下游的抱怨声不绝于耳。当然在合作开发中,文档越完备,双方的理解偏差就越少、开发产生的bug就越少,后期也更容易维护代码、适应人员变更,但是编写完备的文档所需要的额外时间也不容忽视,没有代码产出的设计文档可能不得已让位于现实中整体开发时间的紧张。

    以开发“获得管理员账户下可用商户”为例。如果是简单的描述,后端告知前端url为{host}/ajax/shop,返回的结构是[{"shopId":int,"shopName":string}],有经验的前端会自动判断出MethodGetContent-typeapplication/json,request不需要附带参数,不需要对错误值做特殊处理;而如果是复杂的描述,后端一般会列出API名称、功能描述、调用方式、请求参数、请求示例、返回值、成功的返回结果示例、失败的返回结果示例中的几项,填充到已有的API模板中2
  • 输入效率不高。由于开发的API模板缺乏固定的标准,因此只能在例如Wiki、纯文本编辑器、markdown编辑器中编写,无法得到现代IDE中语法高亮、自动补全、错误提示等特性的支持,整体感觉就像是在记事本中写Java。

    • 设计文档中会规定API输出的数据结构(一般为json数组或者json对象),如果数据结构较为复杂(比如包含有几十个字段的POJO),要在设计文档中书写可读性良好的数据结构需要更多的时间;如果数据结构中字段缺失或者可读性差,则会影响前端的文档理解和代码开发。
    • 如果后端能提供样例数据自然是最好的,因为后端最熟悉业务逻辑,产生的样例数据比前端自己Mock的数据更好。但是复杂数据结构的样例数据的编写同样很花时间。
> 举例:需求要求开发一个新增优惠券API,其样例数据只能由开发手动生成。如果是修改已有的API,要补充新的样例数据,开发一般会登录商户平台,打开优惠券页面,在Chrome中实际操作一遍,抓包得到request的body(json格式),在json格式化网站(如[json.cn](json.cn))美化后复制到API设计文档中。![clipboard.png](/img/bVTWta)
  • 重复录入。因为文档库功能羸弱,使用不便,所以开发一般先按自己的格式写一份文档,但是如果不直接把API录入到公司文档库,则开发需要对一份API出两份设计文档。开发一般会开两个窗口,左边是API设计文档的完成件,右边是公司API文档库编辑页面,然后把左边格式各异的API描述文本转换到右边统一的markdown格式。

    例如:想象一下从Wiki文档的表格中一个个复制粘贴,再编辑成markdown格式文本是典型的成本大于收益的工作。
  • 文档维护成本大。由于文档和代码分开存放,由于需要手动操作,因此文档与代码同步成本较高。随着时间推移,不断修改接口实现的时候都必须同步修改接口文档,而文档与代码又处于两个不同的媒介,除非有严格的管理机制,不然很容易导致不一致现象,并在业务整体交接、开发成员替换时使后来人付出较大的时间成本。

    不同的存放形式的优缺点见仁见智,类似于Spring也有XML和JavaConfig两种配置方式。

2. 减少联调时间

缺少样例数据。由于团队内部前端一般不会全面的了解业务,后端提供的样例数据往往比前端自己生成的Mock数据对业务需求的把握更准确。如果后端能在API设计文档中提供样例数据,一是如果前端没有自动Mock工具的话,能节约前端生成Mock数据的时间;二是能在联调前为前端提前发现一些低级错误(比如具有业务特征的一些默认值处理、空值处理、字段缺失等场景)。

3. 减少部署时间

beta环境绑定了唯一的beta域名,因此在多分支并行开发时是稀缺资源,较大的项目在beta环境编译和部署往往消耗很多等待和解决冲突的时间。如果在联调中发现的问题较多,就需要多次部署beta环境,时间成本十分可观。

如何减少部署时间另外行文

寻找技术候选

总结起来,上面列出的问题大部分是由于API描述标准不统一引起的,因此要用标准化的工厂代替散乱的手工生产。虽然平时开发的API具有Rest风格、对外网开放,只被企业自己的应用调用,不过普遍的WebAPI开发流程还是适用的。我在网上搜索一些功能较为符合的RestAPI设计工具,将其大致分为3类讨论。
clipboard.png

第一类:Swagger、Apiary、RAML

人和机器可读的API描述标准,围绕该语言有完善的工具链:一般有设计、编译(即Codegen)、测试(有MockServer、自动Mock、本地直连等形式)、文档(包括静态文档,如html和pdf;还有可交互文档html+js)、合作(多人+多角色合作开发)这几个模块,各个标准都差不多。

较为学术性的表述:虽然Web API的实现正变得越来越普及,但在工具方面还缺乏一些被广泛接受的标准,用以描述、发现,并且理解大量基于API的服务的意义。Web API之“元语言”有三个关键领域:API描述、API发现以及API档案。所谓的API描述,指的是以一种让人类与机器都可读的形式对API进行描述,包括API的实现细节,例如资源与URL、表述格式(HTML、XML、JSON等等)、状态码以及输入参数。
Swagger、Apiary、RAML的格式各自采取了一种略有不同的设计方式,但在本质上都提供了相同的基本特性:以多种不同级别的细节对Web API进行描述。

以Swagger23为例,分为5个部分(示例图来自于RAML,不过功能都差不多)。
clipboard.png

  • Design:其标准为OpenAPI(前身是Swagger API Spec),提供强大的在线编辑功能,包括语法高亮、错误提示、自动完成、实时预览4,并且支持用户以Json、Yaml格式撰写5、导入、导出、转换文档。
  • Build:设计文档可以编译成客户端和服务端,支持的语言包括Java、NodeJS、C++等主流语言。其中Java服务器端使用流行的Spring Boot构建,生成的代码包括定义的API接口、空实现方法的样板代码、业务POJO、配套的Swagger注解。值得注意的是,由自动生成的Swagger注解,可以反向生成最初的API设计文档
  • Test:可在本地服务器运行时使用本地测试功能;用户也可以使用SwaggerHub中提供收费的在线测试功能,主要有MockServer(Auto Mocking)、问题跟踪(Issue Tracking
  • Document:可以在线或离线(包括代码编译时和运行时)地生成静态html、pdf等文档;SwaggerHub可以配合API版本,自动同步相应文档的版本
  • ShareSwaggerHub提供团队管理、联调开发、文档标注等多人合作开发的支持

再提一下Apiary和RAML。Apiary6使用API Blueprint标准,Apiary网站提供了在线编辑、实时预览、Mock、可交互文档、团队合作、Github同步、流量追踪等包含整个API生命周期的所有服务,当然这是收费产品,而且价格不菲;另外,用户也可以通过开源的命令行工具进行离线的API设计、文档生成、发布过程,并将其集成到自己的工作流中,这也是它的一大特点。RAML使用RAML1.0标准,没有自己的可视化在线开发平台,而是用官方或第三方的离线工具(如API Workbench系列)来代替,因此它也存在一些缺点,比如:工具更新不及时,某些Tool不支持最新的RAML1.0

第二类:Apidocjs

类似于Intellij Idea的生成JavaDoc功能,是一种注释解析器,从C++、Java、Python代码注释中基于特定的关键字(如@param@return)生成API静态文档。由于更像是先代码实现后生成API文档,所以不能算作是设计驱动的开发;另外apidocjs也缺乏IDE支持。

第三类:Rap、eolinker

没有公开的API设计语言,提供在线或离线、闭源或开源的可视化、一体化API开发平台。这里选择中文的Rap、eolinker作为代表。Rap是阿里的开源作品,也提供线上服务,核心功能是文档编辑和自动Mock服务。eolinker是综合的接口管理平台,除了常见的功能,还提供接口商店、数据字典等适合创业团队快速开发API的特性。在此不做进一步介绍。

如何选型?

选型逻辑

  1. 社区活跃、功能完善,应用成熟。
  2. 学习成本低、上手时间短。作为业务开发,缺少时间熟悉学习曲线陡峭的知识和工具。
  3. 功能较多地契合上述优化方向。
  4. 能补充现有工作流的不足,不做大范围的代替。
  5. 要考虑测试环境处于内网造成的障碍。

初步分析

  1. rap、eolinker、swaggerHub、apiary提供了一整套API开发环境,取代了现有工作流。放弃。
  2. apidocjs缺乏现代IDE特性支持,输入效率较低。放弃。

进一步分析

Swagger2API BlueprintRAML
Design在线编辑、IntelliJ Idea插件在线编辑、命令行、Sublime/Atom/Vim插件API Workbench、Sublime/VS插件
Design文档格式yaml、jsonmarkdownyaml
Build支持在线Build、IntelliJ Idea插件/Maven插件
Codegen服务端框架Spring Boot/JAX—RS
Test运行时手动Mock、第三方工具官方和第三方工具生成MockServer/Client第三方工具和在线服务
DocumentMaven插件生成静态文档、在线或运行时生成可交互文档,支持SpringMVC+注解形式第三方工具第三方工具
Share在线、收费在线、收费离线、第三方工具

综合考虑,最后选择Swagger2。因为Swagger对现有的工作流侵入较少;工具较为完整;与团队使用的Spring MVC技术栈无缝集成,可以减轻文档工作量。Swagger2也有一些缺点,如:使用注解方式对代码有侵入性。

用Swagger2优化现有工作流

  1. 减少文档的编写时间

    1. 如果后端先编写独立的API设计文档,可利用Swagger在线编辑器或IDE插件的自动完成等特性;yaml格式统一、简单易懂、表达能力强,较markdown冗余字符更少。通过模仿官方Example很容易学习OpenAPI规定的关键字。
    2. 另外后端也可以把API设计文档直接通过注解的形式,标注在Controller类和相关方法上(以Spring MVCSpring Boot为例),即可以通过Java反射在Maven Complie或运行时生成API设计文档。Swagger有Intellij Idea的插件支持,Swagger注解则能利用现代Java IDE的特性,提高输入效率;另外完善的注解也方便其他开发人员进行后期维护,不需要在设计文档和代码实现中来回切换查看。此种方式相当于面向规约的开发模式,即先规定接口,再填充实现。
  2. 减少文档的转换时间:利用第三方工具实现从Swagger、API Blueprint、RAML格式的互相转换,或者直接输出为html静态文档,方便整合到现在的工作流中。比如:API Blueprint的markdown格式可以存储到公司的API文档库,html静态文档可以存储到内部Wiki。
  3. 减少(可能的)开发时间:如果已有独立的API设计文档,在Swagger Editor中生成基于Maven + Spring Boot的服务端代码,不过生成的POJO和Controller类的命名可能不太理想,需要自己调整。
  4. 减少联调时间:后端可以在设计文档或注解中指定API或者POJO的Example数据,节约前端手动编写Mock数据的时间。

附录1:流程实例演示(脚手架为Spring MVC

1. 标注相应的Swagger注解作为API设计文档

先建立RestController类、相应的API空方法、POJO作为骨架。对应的API设计文档见文末的Reference节。

@Api("Users")
@RestController
@RequestMapping(value = "/users")
public class UserController {@ApiOperation(value = "创建用户", notes = "根据User对象创建用户")@PostMappingpublic String postUser(@RequestBody User user) {return null;}@ApiOperation(value = "获取用户详细信息", notes = "根据url的id来获取用户详细信息")@GetMapping("/{id}")public User getUser(@PathVariable Long id) {return null;}    
}
class User{private Long id;private String name;private String age;//getter,setter
}

2. 生成API设计文档

生成的具体方式按照耗时长短排列为:Maven Complie、Test Case、Server Runtime。可在Swagger Editor中预览相应的可交互文档。根据前端的反馈,修改Swagger注解,并把新的文档存储到内部Wiki或者API文档库(如果改动量大的话,利用Diff工具提高效率)。
clipboard.png

3. 在Swagger-UI提供的可视化页面中完成自测

开发完成后启动Server,Swagger-UI的访问地址为http://localhost:8080/swagger-ui.html

clipboard.png

4. 与前端联调

为了减少beta环境的冲突、加快部署速度,最好在本地开发环境联调。

附录2:Swagger配置与使用

【5分钟指南】Swagger2环境配置与使用

附录3:YAML格式的API描述文档示例

swagger: '2.0'
info:description: Click Link Below for Helpversion: v1title: demo13termsOfService: 'http://www.github.com/kongchen/swagger-maven-plugin'
host: HOST
basePath: /s
tags:- name: Users
schemes:- http
paths:/users:post:tags:- Userssummary: 创建用户description: 根据User对象创建用户operationId: postUserparameters:- in: bodyname: bodyrequired: falseschema:$ref: '#/definitions/User'responses:'200':description: successful operationschema:type: string'/users/{id}':get:tags:- Userssummary: 获取用户详细信息description: 根据url的id来获取用户详细信息operationId: getUserparameters:- name: 'id'in: pathrequired: truetype: integerformat: int64responses:'200':description: successful operationschema:$ref: '#/definitions/User'
definitions:User:type: objectproperties:id:type: integerformat: int64name:type: stringage:type: string

Reference

  1. Swagger:Rest API的描述语言
  2. RAML vs. Swagger vs. API Blueprint
  3. Springfox Reference Documentation
  4. Swagger使用
  5. swagger-maven-plugin
  6. 通过Swagger进行API设计,与Tony Tam的一次对话
  7. API 设计: RAML、Swagger、Blueprint三者的比较
  8. API描述、发现与档案入门
  9. Spring Boot中使用Swagger2构建强大的RESTful API文档
  10. API Design And Documentation
  11. Swagger与其他API文档编写工具对比

  1. 以“云打印机设置”中的一个API为例,简单描述的典型。 clipboard.png
  2. 自定义API模板。 clipboard.png
  3. swagger的Design-Build-Document流程 clipboard.pngclipboard.png
  4. 实时预览。 clipboard.png
  5. Swagger支持YAML格式。clipboard.png
  6. Apiary的Design-Use-Implement流程。 clipboard.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/394340.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

leetcode剑指 Offer 14- I. 剪绳子(动态规划)

给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]…k[m-1] 。请问 k[0]k[1]…*k[m-1] 可能的最大乘积是多少?例如,当绳子的…

数据包提取文件_航测怎样高效提取无人机POS航点数据

无限创新工作室研发的POS数据记录仪是一款采集飞控POS 数据并管理的设备,它将飞控 POS 点数据进行记录,形成单独的POS 数据记录TXT 文本,并独立存储于内存卡,可通过USB、U 盘或内存卡形式对数据进行读取。通过对相机进行拍照控制和…

点击删除表格中的行并提交到数据库

html中&#xff1a; <el-table-column prop"operation" label"操作" width"170"> <template slot-scope"scope"> <el-button size"small" type"danger" click"deleteRow(scope.$index,s…

BZOJ 1878: [SDOI2009]HH的项链

1878: [SDOI2009]HH的项链 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 3548 Solved: 1757[Submit][Status][Discuss]Description HH有一串由各种漂亮的贝壳组成的项链。HH相信不同的贝壳会带来好运&#xff0c;所以每次散步 完后&#xff0c;他都会随意取出一段贝壳&…

分布式 知乎 github_如何使用GitHub本机功能来帮助管理中型分布式团队

分布式 知乎 githubby Alex Ewerlf由AlexEwerlf 如何使用GitHub本机功能来帮助管理中型分布式团队 (How to use GitHub native features to help manage a mid-size distributed team) My team created a wiki page in our private Github repo about how we work on a common…

开始时间小于 结束时间 js_DNF分享红包开始及结束时间 红包有什么奖励相关介绍...

[闽南网]DNF分享红包分享快乐时间从2019年的1月3日开始到1月21日前结束&#xff0c;活动期间玩家每天登录游戏可以得到一个新年红包&#xff0c;使用后可以为同一个频道的玩家送去祝福&#xff0c;根据送出红包的数量得到不同的奖励。(dnf幸运饺子铺活动)(DNF95版新副本攻略)本…

文件的相关操作

将输出的内容直接输出到文件中去 &#xff1a;freopen( “1.txt” , "w" , stdout &#xff09;转载于:https://www.cnblogs.com/ccut-ry/p/7456190.html

leetcode1504. 统计全 1 子矩形(动态规划)

给你一个只包含 0 和 1 的 rows * columns 矩阵 mat &#xff0c;请你返回有多少个 子矩形 的元素全部都是 1 。 示例 1&#xff1a; 输入&#xff1a;mat [[1,0,1], [1,1,0], [1,1,0]] 输出&#xff1a;13 解释&#xff1a; 有 6 个 1x1 的矩形。 有 2 个 1x2 的矩形。 有 3…

学plc好还是python好_PLC是学西门子的好还是学三菱的?

有人回复的很经典&#xff1a;“小孩子才会选择&#xff0c;大人肯定是都要。”如果你是学生&#xff0c;或者正准备踏入这个行业&#xff0c;建议你先学西门子的博途&#xff0c;毕竟这个在国内用的人多些。但是&#xff0c;你要时刻记得&#xff0c;你的目标是星辰大海~~~不要…

wps如何自己制作流程图_怎么制作流程图,wps自动生成流程图方法

在职场中我们要会熟练使用各种办公软件&#xff0c;才能提高我们的工作效率&#xff0c;下面我为大家分享三种制作流程图的方法&#xff0c;非常简单哦&#xff01;一&#xff0c;在Word中制作流程图1&#xff0c;首先点击“插入”再点击“形状”,点击新建绘图画布&#xff0c;…

doom 源码_Cartpole和Doom的策略梯度简介

doom 源码by Thomas Simonini通过托马斯西蒙尼(Thomas Simonini) Cartpole和Doom的策略梯度简介 (An introduction to Policy Gradients with Cartpole and Doom) This article is part of Deep Reinforcement Learning Course with Tensorflow ?️. Check the syllabus here…

SQL 邮件配置篇

在我们运维工作中&#xff0c;经常要对备份&#xff0c;ETL等作业进行监控&#xff0c;这时我们需要用到SQL SERVER自带的邮件服务器&#xff0c;其原理&#xff0c;我在这么里不多说&#xff0c;直接来实战&#xff0c;下面是我对服务器配置源码&#xff0c;分享给大家&#x…

选定用户与用户组启动流程(学习笔记)

public class RepostoryServiceTest {private static final Logger LOGGER LoggerFactory.getLogger(RepostoryServiceTest.class);Rulepublic ActivitiRule activitiRule new ActivitiRule();Testpublic void testRepository(){//repositoryService最重要的功能就是对流程定…

python关于包的题怎么做_Python自定义包引入

python中的Module是比较重要的概念。常见的情况是&#xff0c;事先写好一个.py文 件&#xff0c;在另一个文件中需要import时&#xff0c;将事先写好的.py文件拷贝 到当前目录&#xff0c;或者是在中增加事先写好的.py文件所在的目录&#xff0c;然后import。这样的做法&#x…

汽车之家的安全框架,是如何从0到1搭建的?

“别人家的安全”是安全威胁情报&#xff08;微信ID&#xff1a;Threatbook&#xff09;近期推出的一档专栏。 合规、管理、构建、应急……安全问题千千万&#xff0c;层出不穷。我们没办法给出这些问题的标准答案&#xff0c;但我们可以用Case Study的形式&#xff0c;让你看看…

leetcode264. 丑数 II

编写一个程序&#xff0c;找出第 n 个丑数。 丑数就是质因数只包含 2, 3, 5 的正整数。 示例: 输入: n 10 输出: 12 解释: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 是前 10 个丑数。 说明: 1 是丑数。 n 不超过1690。 解题思路 直接用treeset去重和排序 代码 class Solution …

vr多人_如何构建多人VR网络应用

vr多人by Srushtika Neelakantam通过Srushtika Neelakantam 如何构建多人VR网络应用 (How to build a multiplayer VR web app) In this article, we’ll learn about three great frameworks/libraries that allow any web developer to build a VR app that works on any de…

量子测量 -- 确定性的死神

一、测量 -- 确定性的死神 前文已反复提及在量子世界中测量这一过程会产生很多奇异的、反直觉的现象。在第一篇文章中我举的例子是&#xff1a;用同样的配方&#xff0c;同样的火候&#xff0c;同样的厨具&#xff08;所有你能想到的变量均相同&#xff09;煎鸡蛋&#xff0c;结…

python增删改查csv文件_Python--作业2--对员工信息文件,实现增删改查操作

#!/usr/bin/env python#-*- coding:utf-8 -*-#Author:Huanglinshengimportos#查询方式一&#xff1a;select * from data_staff.txt where age > 22#查询方式二&#xff1a;select * from data_staff.txt where dept "IT"#查询方式三&#xff1a;select * from d…

ios注销所有通知_您一直想了解的有关iOS中通知的所有信息

ios注销所有通知by Payal Gupta通过Payal Gupta 您一直想了解的有关iOS中通知的所有信息 (Everything you’ve always wanted to know about notifications in iOS) 漂亮的小警报..&#xff1f; (Pretty Little Alerts..?) Notifications are a way to inform users when new…