1
API documents can be quickly generated through the Swagger series, but this kind of API document generation requires adding annotations to the interface, which indicates that this is an intrusive way; so is there a non-intrusive way, such as generating documents through annotations? This article mainly introduces the non-intrusive method and the integrated Smart-doc case. The use of tools like Smart-doc when we build a body of knowledge is not the goal, but to understand the extent and technical ideas that can be achieved in a non-intrusive way . @pdai

Prepare knowledge points

Need to understand Swagger intrusiveness and dependencies, and how tools like Smart-Doc solve these problems, partly from the official website . @pdai

Why do tools like Smart-Doc come about?

Now that there is Swagger, why are there tools like Smart-Doc? Essentially Swagger intrusive and dependent.

Let's take a look at the problems with the current mainstream technical documentation tools:

  1. Strong intrusiveness , need to write a lot of annotations, representative tools such as: swagger, and some company-developed documentation tools
  2. Strong dependencies , if the project does not want to use the tool, the business code cannot be compiled.
  3. The code parsing ability is weak, and the documentation is incomplete, mainly representing many open source related tools in China.
  4. Many annotation analysis-based tools cannot parse the annotations in the jar package (sources jar package), and need to manually configure the source code path, which cannot meet the DevOps construction scenario.
  5. Some tools cannot support multi-module complex project code analysis.

What is Smart-Doc? What are the features?

smart-doc is a tool that supports both JAVA REST API and Apache Dubbo RPC interface document generation. smart-doc is the first in the industry to put forward the concept of JAVA generic definition derivation . It analyzes and generates interface documents completely based on the interface source code. Annotations invade into business code. You only need to write comments according to the java-doc standard , and smart-doc can help you generate a simple and clear Markdown, HTML5, Postman Collection2.0+, OpenAPI 3.0+ documentation.
  • Zero annotation, zero learning cost, only need to write standard JAVA annotation.
  • Automatic derivation based on source code interface definitions, powerful return structure derivation.
  • Support Spring MVC, Spring Boot, Spring Boot Web Flux (controller writing method), Feign.
  • Supports the derivation returned by asynchronous interfaces such as Callable, Future, and CompletableFuture.
  • Supports the JSR303 parameter validation specification on JavaBeans, including group validation.
  • The interface for JSON request parameters can automatically generate mock JSON parameters.
  • Some commonly used field definitions can generate valid analog values.
  • Support for generating JSON return value examples.
  • Supports loading source code from outside the project to generate field annotations (including jars published by the standard specification).
  • Support for generating documents in multiple formats: Markdown, HTML5, Asciidoctor, Postman Collection, OpenAPI 3.0. Up- Open document data, free access to document management system.
  • Supports exporting error codes and various dictionary codes defined in the code to the interface document.
  • Support Maven, Gradle plug-in easy integration.
  • Support Apache Dubbo RPC interface document generation.
  • The debug interface to debug html5 pages fully supports file upload and download (@download tag tag download method) testing.

Implementation case

The Maven plugin is officially provided since smart-doc 1.7.9. You can generate documentation directly by integrating the Maven plugin of smart-doc in the project and then running the plugin. Our case is based on the smart-doc-maven-plugin, which generates documentation. The example is written with reference to the official configuration documentation .

configure

Add maven plugin

 <build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
        <plugin>
            <groupId>com.github.shalousun</groupId>
            <artifactId>smart-doc-maven-plugin</artifactId>
            <version>2.4.8</version>
            <configuration>
                <!--指定生成文档的使用的配置文件,配置文件放在自己的项目中-->
                <configFile>./src/main/resources/smart-doc.json</configFile>
                <!--指定项目名称,推荐使用动态参数,例如${project.description}-->
                <!--如果smart-doc.json中和此处都未设置projectName,2.3.4开始,插件自动采用pom中的projectName作为设置-->
                <!--<projectName>${project.description}</projectName>-->
                <!--smart-doc实现自动分析依赖树加载第三方依赖的源码,如果一些框架依赖库加载不到导致报错,这时请使用excludes排除掉-->
                <excludes>
                    <!--格式为:groupId:artifactId;参考如下-->
                    <!--也可以支持正则式如:com.alibaba:.* -->
                    <exclude>com.alibaba:fastjson</exclude>
                </excludes>
                <!--includes配置用于配置加载外部依赖源码,配置后插件会按照配置项加载外部源代码而不是自动加载所有,因此使用时需要注意-->
                <!--smart-doc能自动分析依赖树加载所有依赖源码,原则上会影响文档构建效率,因此你可以使用includes来让插件加载你配置的组件-->
                <includes>
                    <!--格式为:groupId:artifactId;参考如下-->
                    <!--也可以支持正则式如:com.alibaba:.* -->
                    <include>com.alibaba:fastjson</include>
                </includes>
            </configuration>
            <executions>
                <execution>
                    <!--如果不需要在执行编译时启动smart-doc,则将phase注释掉-->
                    <phase>compile</phase>
                    <goals>
                        <!--smart-doc提供了html、openapi、markdown等goal,可按需配置-->
                        <goal>html</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

where ./src/main/resources/smart-doc.json is the configuration file.

 {
  "serverUrl": "http://127.0.0.1", //服务器地址,非必须。导出postman建议设置成http://{{server}}方便直接在postman直接设置环境变量
  "pathPrefix": "", //设置path前缀,非必须。如配置Servlet ContextPath 。@since 2.2.3
  "isStrict": false, //是否开启严格模式
  "allInOne": true,  //是否将文档合并到一个文件中,一般推荐为true
  "outPath": "D://md2", //指定文档的输出路径
  "coverOld": true,  //是否覆盖旧的文件,主要用于markdown文件覆盖
  "createDebugPage": true,//@since 2.0.0 smart-doc支持创建可以测试的html页面,仅在AllInOne模式中起作用。
  "packageFilters": "",//controller包过滤,多个包用英文逗号隔开,2.2.2开始需要采用正则:com.test.controller.*
  "md5EncryptedHtmlName": false,//只有每个controller生成一个html文件时才使用
  "style":"xt256", //基于highlight.js的代码高设置,可选值很多可查看码云wiki,喜欢配色统一简洁的同学可以不设置
  "projectName": "pdai-springboot-demo-smart-doc",//配置自己的项目名称,不设置则插件自动获取pom中的projectName
  "skipTransientField": true,//目前未实现
  "sortByTitle":false,//接口标题排序,默认为false,@since 1.8.7版本开始
  "showAuthor":true,//是否显示接口作者名称,默认是true,不想显示可关闭
  "requestFieldToUnderline":true,//自动将驼峰入参字段在文档中转为下划线格式,//@since 1.8.7版本开始
  "responseFieldToUnderline":true,//自动将驼峰入参字段在文档中转为下划线格式,//@since 1.8.7版本开始
  "inlineEnum":true,//设置为true会将枚举详情展示到参数表中,默认关闭,//@since 1.8.8版本开始
  "recursionLimit":7,//设置允许递归执行的次数用于避免一些对象解析卡主,默认是7,正常为3次以内,//@since 1.8.8版本开始
  "allInOneDocFileName":"index.html",//自定义设置输出文档名称, @since 1.9.0
  "requestExample":"true",//是否将请求示例展示在文档中,默认true,@since 1.9.0
  "responseExample":"true",//是否将响应示例展示在文档中,默认为true,@since 1.9.0

  "ignoreRequestParams":[ //忽略请求参数对象,把不想生成文档的参数对象屏蔽掉,@since 1.9.2
    "org.springframework.ui.ModelMap"
  ],
  "dataDictionaries": [{ //配置数据字典,没有需求可以不设置
    "title": "http状态码字典", //数据字典的名称
    "enumClassName": "tech.pdai.springboot.smartdoc.constant.ResponseStatus", //数据字典枚举类名称
    "codeField": "responseCode",//数据字典字典码对应的字段名称
    "descField": "description"//数据字典对象的描述信息字典
  }],
  "errorCodeDictionaries": [{ //错误码列表,没有需求可以不设置
    "title": "title",
    "enumClassName": "tech.pdai.springboot.smartdoc.constant.ResponseStatus", //错误码枚举类
    "codeField": "responseCode",//错误码的code码字段名称
    "descField": "description"//错误码的描述信息对应的字段名
  }],
  "revisionLogs": [{ //文档变更记录,非必须
    "version": "1.1", //文档版本号
    "revisionTime": "2022-07-01 22:12:01", //文档修订时间
    "status": "update", //变更操作状态,一般为:创建、更新等
    "author": "pdai", //文档变更作者
    "remarks": "init user api" //变更描述
  },{ //文档变更记录,非必须
    "version": "1.2", //文档版本号
    "revisionTime": "2022-07-01 22:12:02", //文档修订时间
    "status": "update", //变更操作状态,一般为:创建、更新等
    "author": "pdai", //文档变更作者
    "remarks": "add address api" //变更描述
  }
  ],
  "customResponseFields": [{ //自定义添加字段和注释,一般用户处理第三方jar包库,非必须
    "name": "code",//覆盖响应码字段
    "desc": "响应代码",//覆盖响应码的字段注释
    "ownerClassName": "org.springframework.data.domain.Pageable", //指定你要添加注释的类名
    "ignore":true, //设置true会被自动忽略掉不会出现在文档中
    "value": "00000"//设置响应码的值
  }],
  "requestHeaders": [{ //设置请求头,没有需求可以不设置
    "name": "token",//请求头名称
    "type": "string",//请求头类型
    "desc": "desc",//请求头描述信息
    "value":"token请求头的值",//不设置默认null
    "required": false,//是否必须
    "since": "-",//什么版本添加的改请求头
    "pathPatterns": "/app/test/**",//请看https://gitee.com/smart-doc-team/smart-doc/wikis/请求头高级配置?sort_id=4178978
    "excludePathPatterns":"/app/page/**"//请看https://gitee.com/smart-doc-team/smart-doc/wikis/请求头高级配置?sort_id=4178978
  },{
    "name": "appkey",//请求头
    "type": "string",//请求头类型
    "desc": "desc",//请求头描述信息
    "value":"appkey请求头的值",//不设置默认null
    "required": false,//是否必须
    "pathPatterns": "/test/add,/testConstants/1.0",//正则表达式过滤请求头,url匹配上才会添加该请求头,多个正则用分号隔开
    "since": "-"//什么版本添加的改请求头
  }],
  "requestParams": [ //设置公共参数,没有需求可以不设置
    {
      "name": "configPathParam",//请求名称
      "type": "string",//请求类型
      "desc": "desc",//请求描述信息
      "paramIn": "path", // 参数所在位置 header-请求头, path-路径参数, query-参数
      "value":"testPath",//不设置默认null
      "required": false,//是否必须
      "since": "2.2.3",//什么版本添加的该请求
      "pathPatterns": "/app/test/**",//请看https://gitee.com/smart-doc-team/smart-doc/wikis/请求高级配置?sort_id=4178978
      "excludePathPatterns":"/app/page/**"//请看https://gitee.com/smart-doc-team/smart-doc/wikis/请求高级配置?sort_id=4178978
    }],
  "responseBodyAdvice":{ //自smart-doc 1.9.8起,非必须项,ResponseBodyAdvice统一返回设置(不要随便配置根据项目的技术来配置),可用ignoreResponseBodyAdvice tag来忽略
    "className":"tech.pdai.springboot.smartdoc.entity.ResponseResult" //通用响应体
  }
}

run the test

Documentation can be generated via Maven commands

 //生成html
mvn -Dfile.encoding=UTF-8 smart-doc:html

In IDEA, it is also possible to build via the maven plugin

The maven build log is as follows

 [INFO] Scanning for projects...
[INFO] 
[INFO] --------------< tech.pdai:115-springboot-demo-smart-doc >---------------
[INFO] Building 115-springboot-demo-smart-doc 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] >>> smart-doc-maven-plugin:2.4.8:html (default-cli) > compile @ 115-springboot-demo-smart-doc >>>
[INFO] 
[INFO] --- maven-resources-plugin:3.2.0:resources (default-resources) @ 115-springboot-demo-smart-doc ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Using 'UTF-8' encoding to copy filtered properties files.
[INFO] Copying 0 resource
[INFO] Copying 1 resource
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ 115-springboot-demo-smart-doc ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] <<< smart-doc-maven-plugin:2.4.8:html (default-cli) < compile @ 115-springboot-demo-smart-doc <<<
[INFO] 
[INFO] 
[INFO] --- smart-doc-maven-plugin:2.4.8:html (default-cli) @ 115-springboot-demo-smart-doc ---
[INFO] ------------------------------------------------------------------------
[INFO] Smart-doc Start preparing sources at: 2022-07-01 22:43:54
[INFO] Artifacts that the current project depends on: ["org.springframework.boot:spring-boot-starter-web","org.springframework.boot:spring-boot-configuration-processor","org.projectlombok:lombok"]
[INFO] Smart-doc has loaded the source code path: [{"path":"D:/git/tech-pdai-spring-demos/115-springboot-demo-smart-doc/src/main/java"}]
[INFO] Smart-doc Starting Create API Documentation at: 2022-07-01 22:43:54
[INFO] API documentation is output to => D://md2
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  2.196 s
[INFO] Finished at: 2022-07-01T22:43:55+08:00
[INFO] ------------------------------------------------------------------------

The constructed html is as follows:

You can also see that the mock data is also automatically provided, as well as the button to test the interface. Also includes custom return enumeration types, etc.

For the display effect, please refer to https://api.doubans.com/

Generate more types of documents

smart-doc also supports generating the following types of documentation:

 //生成markdown
mvn -Dfile.encoding=UTF-8 smart-doc:markdown
//生成adoc
mvn -Dfile.encoding=UTF-8 smart-doc:adoc
//生成postman json数据
mvn -Dfile.encoding=UTF-8 smart-doc:postman
// 生成 Open Api 3.0+, Since smart-doc-maven-plugin 1.1.5
mvn -Dfile.encoding=UTF-8 smart-doc:openapi

further understanding

Combined with the official smart-doc documentation, we further understand smart-doc through several questions. The main content comes from the official documentation .

Comment information is limited, how does smart-doc expand the document content from comments?

We know that the annotation information is limited. The swagger technology stack constrains and expands the content of the document by defining annotations. So how does smart-doc expand the content of the document from annotations?

On the one hand smart-doc the original intention of the realization is to use the javadoc document comment to remove the annotated intrusion, so smart-doc each additional function should be considered first javadoc native tag ,

The following is an introduction to some of the notes used by smart-doc javadoc tag .

tag name Description of use
@param For the Spring Boot interface layer, for simple type parameters, you must write a comment description when using @param , for Entity type smart-doc won't check
@deprecated It can be used in comments to mark that the interface has been deprecated, and the function is the same as @Deprecated annotation
@apiNote @apiNoteJAVA新增的文档tag , smart-doc @apiNote的详细描述, So you can use @apiNote to write a long comment. If a method does not write @apiNote annotation description, smart-doc fill directly with the method default annotation

On the other hand, the native tag is not enough, so smart-doc also supports the expansion of more functions through custom tags

tag name describe
@ignore @ignore tag Used to filter a field on the request parameter object, after setting smart-doc do not output the changed field to the request parameter list. For details on ignoring response fields, see [Ignore Response Fields] If @ignore is added to the method, the interface method will not be output to the document. Starting from 1.8.4 @ignore support was added to Controller to ignore interface classes that do not want to generate documentation. @ignore can also be used to ignore a request parameter on a method.
@required If you do not use the JSR303 parameter validation specification implementation to annotate fields, you can use @required to annotate the fields of the request parameter object, and annotate smart-doc in the output parameters When listing, it will be set to true .
@mock Starting from smart-doc 1.8.0 , @mock tag is used to set the custom document display value in the object base type field. After setting the value smart-doc no longer generates random values for you. It is convenient to directly output the delivery document through smart-doc .
@dubbo smart-doc 1.8.7 1fc776e58c77bbd331d6a66bcf41122b---开始, @dubbo tagDubboAPI smart-doc can scan to the interface of Dubbo RPC to generate documents.
@restApi smart-doc 1.8.8 0ea0545a278d5fe32efce71c3837395b---开始, @restApi tag支持smart-doc去扫描---ee76ebf3623ff0e7697ff122c73683d2---的Spring Cloud Feign文档。
@order smart-doc 1.9.4 321845271b86bfc6f00ffdf66bec2af4---开始, @order tag用于设置---676b4884c7f53f55e019237488bfe197 Controller API入口的自定义排序序号, @order 1 means the set serial number is 1 .
@ignoreResponseBodyAdvice Starting from smart-doc 1.9.8 , @ignoreResponseBodyAdvice tag is used to ignore the wrapper class of ResponseBodyAdvice set.
@download smart-doc 2.0.1 694c00ac0ccaef0709357a6fc0c39eea---开始, @download tag Controller的文件下载方法上, debug页面When the file download test can be achieved. And support download file with request header parameter test.
@page smart-doc 2.0.2 1bb9b9f0e7fc71b045384fdcf337b170---开始, @page tag用于标注在---7e5e091d000f7a026fc6254dff2e6192 Controller的方法上表示该方法用来渲染返回一个静态页面,生成debug If you initiate a test on a page, the test page will automatically open a new tab in the browser to display the page.
@ignoreParams smart-doc 2.1.0 3746e87079681c7725fdce0ffa64ee06---开始, @ignoreParams tag用于标注在---d049d7f4a7f2087a73396e6a59ab2634 Controller方法上忽略掉不想显示在文档中的参数,例如: @ignoreParams id name , multiple parameter names are separated by spaces
@response smart-doc 2.2.0 c7349cdb5e36444baa6a660bd7de46ac---开始, @response tag标注在---4a25d44488603126f90a625b2336f319 Controller方法上可以允许用这自己定义返回的json example . It is recommended to use only when returning primitive types, such as: Result<String> type This generic type is the response of a simple primitive type.
@tag @since 2.2.5 , @tag Controller方法分类, 可以将不同---aa78976e30483c3f22cb1a04992408fa Contoller下的方法指定到多个分类下, 同时也You can directly specify Controller for one category or multiple categories

Is there a better practice for using plugins in Maven multi-modules?

Using smart-doc in a standalone Maven project is currently silky smooth. But when using smart-doc-maven-plugin in Maven's multi-module project, many students have questions, where should I put the smart-doc plugin? Is it placed in the root pom.xml of Maven? Or in each module that needs to generate API interface documentation? Let's talk about how to put plugins according to different project structures.

Complete parent-child relationship of maven project:

 ├─parent
├──common
│   pom.xml
├──web1
│   pom.xml
├──web2
│   pom.xml
└─pom.xml

The above maven structure is assumed to be configured strictly according to the parent-child level, and then both web1 and web2 depend on common. In this case, if you run the mvn command directly to the web1 or web2 directory to compile, it will not be completed. You need to execute the command compilation command in the root directory to pass, and the smart-doc plugin will load some classes configured by the user through the class loader, so it is necessary to call the compilation and execute the command is the same. In this case, it is recommended that you build the smart-doc-maven-plugin and put it in the root pom.xml, and put the respective smart-doc.json configuration in web1 and web2. Then pass -pl to specify to let smart-doc generate documentation for the specified module. The operation command is as follows:

 # 生成web1模块的api文档
mvn smart-doc:markdown -Dfile.encoding=UTF-8  -pl :web1 -am
# 生成web2模块的api文档
mvn smart-doc:markdown -Dfile.encoding=UTF-8  -pl :web2 -am

If it is not a project built according to a strict parent-child hierarchy, it is still the structure example above. The common module is placed in the class parent, but the common pom.xml does not define parent. The common module is also rarely changed. Many companies may directly upload the common separate depoly to the company's Nexus warehouse. In this case, although web1 and web2 depend on common, both web1 and web2 can be used in the web1 and web2 directories. Command compilation. In this case, you can build and generate documents by directly placing the smart-doc-maven-plugin in web1 and web2 separately.

[ Multi-module test case reference ]

Note: There is no fixed pattern for how to use the plugin. The most important thing is to be proficient in some series of Maven operations, and then adjust it according to your own project situation. Skilled to deal with it easily. For the use of plugins, starting from smart-doc-maven-plugin 1.2.0, the plugin can automatically analyze the dependencies of the generated modules to load the necessary source code, and does not combine the interface documents of all modules into one document.

How can I debug if I have problems generating the documentation?

Some errors may occur in the process of using the smart-doc-maven-plugin plugin to build and generate the API document. The official documentation provides a solution for debugging:
  1. Add smart-doc dependency

Because smart-doc-maven-plugin is finally used smart-doc to complete the source code analysis and document generation of the project,
Usually the real debug code is smart-doc . But this process is mainly checked by smart-doc-maven-plugin .

 <dependency>
     <groupId>com.github.shalousun</groupId>
     <artifactId>smart-doc</artifactId>
     <version>[最新版本]</version>
     <scope>test</scope>
</dependency>

Note: It is best to use the version of smart-doc that the plugin depends on smart-doc .

  1. Add breakpoint

Add breakpoints as shown

  1. Run the build target in Debug mode

maven plugin runs in idea debug is very simple, the operation is as shown below.

This will let you go directly to the breakpoint.

Tip: The above is the source code for debugging smart-doc through the plug-in. If you want to debug the source code execution process of the plug-in itself, then add the plug-in dependencies to the project dependencies, as follows:

 <dependency>
    <groupId>com.github.shalousun</groupId>
    <artifactId>smart-doc-maven-plugin</artifactId>
    <version>【maven仓库最新版本】</version>
</dependency>

Then debug the source code of smart-doc-maven-plugin through similar steps above

Sample source code

https://github.com/realpdai/tech-pdai-spring-demos

https://smart-doc-group.github.io/

more content

Say goodbye to fragmented learning, one-stop systematic learning without routines Back-end development: Java full-stack knowledge system (https://pdai.tech)


pdai
67 声望158 粉丝