背景
最近开发Java后台新项目,考虑到要向前端或别的业务部门交互API文档,所以在想如何方便快捷地实现。最好的方式从代码里就能直接生成。根据以往的经验,swagger2是一个不错的选择,只要在代码里加上相关注解,就能生成html或markdown格式的文档。在一次偶然的机会,得知还有一个叫smart-doc的东东, 号称零注解,对代码倾入性很小。决定安排人来试试。总体使用下来,确实比swagger2方便,只需在注释里加点东西就行,不用在代码里引入其它类或注解。
引入
smart-doc的国内地址, 它在github上也有地址,相比起来,国内访问的较快。我们主要是通过maven来引入的,然后生成文档也是通过maven的方式。
首先在pom.xml里build部分加入一个plugin,如下:
<plugin>
<groupId>com.github.shalousun</groupId>
<artifactId>smart-doc-maven-plugin</artifactId>
<version>2.2.1</version>
<configuration>
<!--Specify the configuration file used to generate the document-->
<configFile>./src/main/resources/smart-doc.json</configFile>
<projectName>consoleBiz</projectName>
</configuration>
</plugin>
接着在工程的resources下加入一个它的配置文件smart-doc.json, 如下即可。参考smart-doc的文档,可配置的项还有很多,可以根据需要自己配置。
{
"projectName": "console-biz",
"allInOne": true,
"allInOneDocFileName": "restful.html",
"isStrict": false,
"outPath": "./docs/api",
"coverOld": true
}
然后通过下面命令就能生成文档。可以是html或md(markdown)格式。
# md
mvn -Dfile.encoding=UTF-8 smart-doc:markdown
# html
mvn -Dfile.encoding=UTF-8 smart-doc:html
感觉html格式的,更好,有导航。但需要弄个nginx跑起来才行。在gitlab里,还是md的方便些。下面是截图:
注意事项
-
API文档是通过RestController或Controller的注释来生成的
-
如果接口不想体现在api文档里,可以使用@ignore加到restcontroller的类或方法上
-
注解要用/** */格式,如用// 是无效的。如下:
/**
* 用户信息
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserInfo implements java.io.Serializable{
/** 版本号 */
private static final long serialVersionUID = 1L;
/** 用户id */
@TableId
private String id;
/** 用户名 */
private String name;
// 业务角色, 这个无法通过smart-doc来呈现
@TableField(exist = false)
private BizRole bizRole;
}
- 有些提交参数,在添加或修改时必填,在查询时非必填,可使用spring validation的分组机制。smart-doc会识别validation的标签,然后在文档里就能显示是否必填。举例如下:
对象SysRole的roleName在添加修改是必填的,查询时可以不填。通过groups加了分组校验
/**
* 系统角色
*/
@Data
public class SysRole implements java.io.Serializable {
/**
* 版本号
*/
private static final long serialVersionUID = 1L;
/**
* id
*/
@TableId(type = IdType.AUTO)
@NotNull(groups = {OprUpdate.class}, message = "{validation.id}")
private Integer id;
/**
* 角色名
*/
@NotBlank(groups = {OprAdd.class, OprUpdate.class}, message = "{validation.roleName}")
private String roleName;
/**
* 描述
*/
private String description;
}
// RestController的设置
/**
* 添加系统角色
* @param sysRole
* @return
*/
@PostMapping("/addSysRole")
public ResultInfo addSysRole(@Validated(value = {OprAdd.class}) @RequestBody SysRole sysRole) {}
/**
* 修改系统角色
* @param sysRole
* @required id
* @return
*/
@PutMapping ("/updateSysRole")
public ResultInfo updateSysRole(@Validated({OprUpdate.class}) @RequestBody SysRole sysRole) {}
/**
* 按条件查询系统角色
* @param pageNum 页码
* @param pageSize 每页条数
* @param condition
* @return
* @response {
* "result": 0,
* "data": {
* "records": [
* {
* "id": 6,
* "roleName": "test-99"
* }
* ],
* "total": 4,
* "size": 1,
* "current": 3,
* "orders": [],
* "optimizeCountSql": true,
* "searchCount": true,
* "pages": 4
* }
* }
*/
@PostMapping("/getSysRolesByCondition")
public ResultInfo getSysRolesByCondition(@RequestParam(name="pageNum",required = false,defaultValue = "1") Integer pageNum,
@RequestParam(name = "pageSize",required = false, defaultValue = "10") Integer pageSize,
@Validated({OprQuery.class}) @RequestBody SysRole condition) {
文档生成的效果图
- 如接口返回的是一个业务对象,那么smart-doc会将对象的属性注释返回。但有时我们还要加上一些错误原因。所以一般会将返回信息放到一个统一返回对象里。里面通过Object来代表实际的值,result表示成功已否,reason代表原因。这时就需要在注释里用@response来表示返回的值格式。参见上面getSysRolesByCondition()方法的注释。
/**
* 返回对象
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ResultInfo implements Serializable{
/**
* 结果类型
* 0 : OK
* 1 : 业务异常,一般前端要提示给用户
* 2 : 系统异常,一般前端就console.log,不提示给用户
*/
@Builder.Default
private int result = -1;
/**
* 出错原因,如成功则为空
*/
@Builder.Default
private String reason = null;
/**
* 返回数据
*/
private Object data;
}
文档呈现的效果如下, data的格式就是在注解里通过@response来表示的:
后记
smart-doc还支持api测试,不光光是一个文档生成器,后续研究研究。