Duo-Doc是对javadoc的扩展,对代码无入侵,在代码编辑期通过读取分析代码注释、项目文件结构、markdown文档,抽取接口及文档信息,并由一个前端项目展示成接口文档,提供接口调用和mock等功能。
目前已实现两类接口文档的生成:
spring mvc提供的 @RestController
注解的类和由@RequestMapping
/ @GetMapping
/ @PostMapping
/ @PutMapping
/ @PatchMapping
/ @DeleteMapping
注解的方法
@com.alibaba.dubbo.config.annotation.Service注解的Dubbo接口
使用xml配置的dubbo服务接口
本工具以maven插件方式提供,使用本自动化文档系统只需要:多写注释,多写注释,多写注释!
文档结构分为三级:
章节(Chapter): 一级分类
模块(Section):二级分类
文章(Article):接口文档
在服务入口模块的pom.xml文件build
> plugins
内添加以下代码
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.3</version>
<configuration>
<doclet>com.duoec.doc.doclet.DuoDoclet</doclet>
<docletArtifact>
<groupId>com.duoec.doc</groupId>
<artifactId>duo-doclet</artifactId>
<!-- duo-doc version -->
<version>1.2-SNAPSHOT</version>
</docletArtifact>
<sourcepath>
<!-- 指定源码路径,如果多个模块,需要包含进去,多个目录使用半角冒号分隔 -->
${project.basedir}/src/main/java:${project.basedir}/../article-service-api/src/main/java
</sourcepath>
<useStandardDocletOptions>false</useStandardDocletOptions>
<additionalJOptions>
<additionalJOption>-J-Dbasedir=${project.basedir}</additionalJOption>
<!-- 可选,如果没有填写,则会使用当前服务的{groupId}:{artifactId} -->
<!-- 如果使用了mock功能时,必填 -->
<additionalJOption>-J-DappId=article.duo</additionalJOption>
<!-- 可选,server指定接口数据往哪个地方上报,默认为:http://doc.duoec.com -->
<additionalJOption>-J-Dserver=http://doc.duoec.com</additionalJOption>
<!-- 可选,上报git commit id,目前用于duo-graphql接口版本 -->
<!-- 需要依赖插件 pl.project13.maven:git-commit-id-plugin -->
<additionalJOption>-J-DcommitId=${git.commit.id}</additionalJOption>
</additionalJOptions>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
<!-- package可以在提交代码后由CI自动触发 -->
<!-- 如果不需要自动触发,可以设置为site,届时需要手工执行:mvn clean site -->
<phase>package</phase>
<goals>
<goal>javadoc</goal>
</goals>
</execution>
</executions>
</plugin>
引入的新构建模块插件需要注意:
plugin
>configuration
>sourcepath
需要按项目实际情况调整,将需要扫描的源码路径添加进来即可
plugin
配置需要添加到打包部署包的模块上maven的勾子可设置为
package
,代码提交时会由CI触发,即每次代码提交都会更新文档,如果不需要自动触发,可配置为site
,然后手工执行:mvn clean site,手工更新文档
创建完成后,会在日志里面打印出文档的地址(PS,截图上的链接地址有变化,以实际显示为准):
文档地址默认使用此模块的maven(不包含版本号),即是升级了版本后访问地址还是不变的,查看旧版本的文档可以在历史文档中找到
目前接口文档支持两种类型:
RestFul接口: 通过文章ID拉取文章信息
Dubbo接口:文章内链、敏感词格式化
目前接入的项目索引:项目索引
写文档其它就是写java注释!看下面的一段代码
/**
* 小区列表接口
*
* @chapter 小区
* @section 小区推荐
*/
@RestController
@RequestMapping("/cell")
public class CellApiController {
/**
* 相似小区列表
* 从数据团队提供的接口里获取到小区ID,再通过搜索接口,获取小区详情
*
* @param request 请求参数
* @return 小区列表
*/
@RequestMapping(value = "/similar", method = RequestMethod.POST)
public BaseResponse<List<CellInfoDto>> getSimilarCellList(@RequestBody SimilarCellReqDto request) {
//...
}
}
只在被注解为@RestController
的类才会被当成RestFul
接口进行解析,否则丢弃
类注释里面:
@chapter
表示指定章节(Chapter),默认为接口文档
@section
表示指定模块(Section),默认为当前类第一行注释,如果没有写注释,则为类全名。如果未指定@section
但有多行注释时,会取第一行注释为模块名,其它为模块注释
PS:暂未实现将@RestController
写在父类的场景
如果添加注释@disable
,则整个Controller的文档都不会被创建
Controller里面的方法,只要被注解为@RequestMapping
/ @GetMapping
/ @PostMapping
/ @PutMapping
/ @PatchMapping
/ @DeleteMapping
,就会被当成RestFul
接口处理,生成对应的一篇接口文档(Article)
这些注解的属性:
value
与Controller
里的@RequestMapping
内的value
属性一起当成接口路径。如果有多个时,会平铺开当
@RequestMapping
属性method
没有指定值时,文档中会显示成GET
/POST
(这里没有把PUT
/DELETE
等显示出来)
@api
表示指定接口名称,如果没有指定,尝试使用第一行注释,其它注释当成接口注释。如果也没有写注释,则使用方法名称作为接口名称
@param
参数的注释,会出现在文档的参数表格里面,如果没有指定则没有注释信息(暂时实现默认值的写法)
@return
响应的注释
如果添加注释@disable
,则本接口的文档都不会被创建
如果添加注释@disableInvoke
,则本接口的文档都允许在Duo-Doc中调用
请求参数的说明可以在方法注释的@param
里写,但如果请求参数是一个bean
,则可以在类属性里写更丰富的信息
支持spring mvc
的参数注解:
@PathVariable
:路径参数,必填,使用了正则限制的,在接口调用中还会对参数进行校验
@RequestBody
:Post Body参数,非必填,支持复杂结构类,类的注释说明见下文
@RequestParam
:默认必填,也可以通过属性required
声明是否必填,使用defaultValue
声明默认值。如果参数是没有带任何注解,也相当于使用此注解,必填
@RequestAttribute
:一般是由Filter或拦截器注入的,所以不把它当成是请求参数,不会出现在文档里面
@RequestHeader
:是由请求头注进来的,暂时也不体现在文档中
自定义注解暂不支持
响应体的说明可以在@return
里写,同时,如果是个bean
时也可以在类里面写更多的信息,参考下文Bean
的说明
请求参数与响应体都可以是一个Bean
,看下面的案例:
/**
* 标准响应体,这里可以写些类的说明
*/
public class BaseResponse<T> {
/**
* 响应值: 200=正常 其它值表示有异常
* @demo 200
*/
private Integer code;
/**
* 信息,一般在响应异常时有值
* @required
* @demo 用户名不能为空
*/
private String msg;
/**
* 响应数据
*/
private T data;
//getter和setter
}
类属性的注释非常重要,尽量写明白它的含义。另外,属性必需有对应的getter和setter,否则会被show me
丢弃。当然,我们也支持lomok的 @Data
/ @Getter
/ @Setter
注解。
可以使用以下注解标识属性必填,不能为空:
@javax.validation.constraints.NotNull
@required
@org.hibernate.validator.constraints.NotBlank
@org.hibernate.validator.constraints.NotEMPTY
默认属性是可为空的,也可以使用注解:
@javax.validation.constraints.Null
@demo
是指明此属性的demo值,让生成的文档更直观
如果Bean
包含泛型,为生成完整的文档,强烈建议在定义里定义好泛型类型!
如果是java.util.Date
类型时,如果有指定@demo
值,则直接使用指定的值;
否则,如果有使用注解org.springframework.format.annotation.DateTimeFormat
则会使用当前时间根据注解配置的格式转换成字符串显示;
如果也没有使用注解,则使用new Date().toString()
的值显示
建议:不要使用java.util.Date
类型!可以使用时间戳类型。
枚举类型,使用@demo
值,未指定时,为空。
/**
* DEMO接口
* @chapter Demo接口
* @section Demo1
* @c1 10
* @c2 10
*/
@RestController
@RequestMapping("/demo")
public class DemoApiController {
/**
* 接口1
* 这里注释的第一行会被当成是接口的名称,第二行被当成是接口说明
* @c3 10
* @return
*/
@RequestMapping(value = "/api1")
public BaseResponse api1() {
return BaseResponse.success();
}
/**
* 这里的文字会被当成接口注释
* @api 接口2
* @return 返回热门标签
*/
@RequestMapping(value = "/api2")
public BaseResponse<List<Tag>> api2() {
return BaseResponse.success();
}
}
上面代码中,响应体BaseResponse
是带泛型的,所以在写接口时,api1()
是不推荐的写法,因为没有指定响应体内容,生成的文档时也没办法去识别它的响应体结构
api2()
是一种推荐的写法,指定了泛型,这样在生成文档时,就可以根据泛型的类型继续深挖它的结构,最后生成出来的文档会非常明了
如果Bean
属性出现了循环引用的情况下,生成的文档会使用下面的方式表达,比如
public class User<T> {
/**
* 上级用户
*/
private User<T> parent; //这里也使用了当前类
}
会生成以下文档:
注释标签 | 范围 | 说明 | DEMO |
---|---|---|---|
@c1 | 类 | 一级分类,即 @chapter 排序 | @c1 10 |
@c2 | 类 | 二级分类,即 @section 排序 | @c2 10 |
@c3 | 方法 | 接口排序,即 @api 排序 | @c3 10 |
排序值越小越前
dubbo文档的生成规则与RestFul的完全一致,请参考上面RestFul说明
注意,dubbo接口的文档以接口的注释为准,实现类的注释暂未采集!
@com.alibaba.dubbo.config.annotation.Service注解的Dubbo接口,文档的说明以接口的注释为准,实现里的注释暂时未采用,后继将使用上
可以通过插件配置中的变更dubboXmlConfigs
配置需要加载的dubbo
配置文件,文件使用相对于{baseDir}/src/main/resources/
的相对目录,多个文件使用英文逗号分隔:
<additionalJOption>-J-DdubboXmlConfigs=dubbo-config.xml,dubbo/dubbo-config1.xml</additionalJOption>
系统支持自定义markdown文档,markdown文档默认是在启动项目下的doc
,以.md
为后缀。
如果需要改变可以通过插件配置指定目录:
<additionalJOption>-J-DmarkdownDir=docs</additionalJOption>
默认,项目需要一个REDME.md
文件,项目文档根目录中显示(参考github的项目首页)
另外,如果文件名跟分类名匹配时,会将文档的链接加在分类上,比如有个分类目录为:公共接口
/相册接口
在文档目录中有两个文件:doc/公共接口/相册接口/README.md
和 doc/公共接口/README.md
生成的目录结构会显示成下图那样,是带链接的,同时分类前面的icon也会显示成markdown的标识。
/**
* 标签
* @demo [笋盘, 满五唯一]
*/
private List<String> tags;
上面字段tags
的注释,因为是List<String>
类型,应该写为:@demo ["笋盘", "满五唯一"]
这种错误可能会影响restful
代码调用时的request body
demo 值
上面所有的注释标签都可以进行自定义
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )