猿创征文|小而巧的API文档生成工具之smart-doc

文章目录

smart-doc介绍

一个 java restful api 文档生成工具不用像Swagger一样写大量注解,完全基于接口源码分析来生成接口文档,但是需要 按照 java的标准注释写。

完全基于接口源码来分析生成接口文档,不采用任何注解侵入到业务代码中。

你只需要按照 java-doc标准编写注释, smart-doc就能帮你生成一个简易明了的 MarkdownHTML5Postman ollection2.0+OpenAPI 3.0+的文档。

注意:需要完全按照java的标准注释,如果方法注释包含特殊符号或者换行的话,生成的json是会出现格式错误,但是不影响相关的html使用。

smart-doc特性

  • 零注解、零学习成本、只需要写标准 JAVA注释。
  • 基于源代码接口定义自动推导,强大的返回结构推导。
  • 支持 Spring MVCSpring BootSpring Boot Web Flux(Controller书写方式) Feign
  • 支持 CallableFutureCompletableFuture等异步接口返回的推导。
  • 支持 JavaBean上的 JSR303参数校验规范,包括分组验证。
  • JSON请求参数的接口能够自动生成模拟 JSON参数。
  • 对一些常用字段定义能够生成有效的模拟值。
  • 支持生成 JSON返回值示例。
  • 支持从项目外部加载源代码来生成字段注释(包括标准规范发布的jar包)。
  • 支持生成多种格式文档: MarkdownHTML5AsciidoctorPostman CollectionOpenAPI 3.0。 开放文档数据,可自由实现接入文档管理系统。
  • 支持导出错误码和定义在代码中的各种字典码到接口文档。
  • 支持 MavenGradle插件式轻松集成。
  • 支持 Apache Dubbo RPC接口文档生成。
  • debug接口调试 html5页面完全支持文件上传,下载(@download tag标记下载方法)测试。

smart-doc的最佳搭档

smart-doc + Torna 组成的文档生成和管理解决方案,使用 smart-doc无侵入完成 JAVA源代码分析和提取注释生成 API文档,自动将文档推送到 Torna企业级接口文档管理平台。

猿创征文|小而巧的API文档生成工具之smart-doc

; 谁在使用smart-doc

猿创征文|小而巧的API文档生成工具之smart-doc

smart-doc的优缺点

简单总结了几个特别明显以及我认为最关键的几个优点如下:

  • 非侵入式接口文档生成
  • 需要按照java文档注释规范对接口及相关对象添加注释
  • 编译文件后需要手动运行插件生成接口文档
  • 配置简单,只需要引入插件,配置文档输出位置即可。相关更加复杂的配置根据需要自行配置。
  • 无需启动项目,生成文档后可直接浏览

缺点
我总结了一下我使用过程中的缺点,在此我仅代表我自己提出的缺点如下

  • 生成的openapi.json数据时,不支持泛型的多层嵌套解析,导致不同接口的responseBody解析为一个。比如接口返回为: ResultVO<definepage<aioptimizationcampaignreportvo>></definepage<aioptimizationcampaignreportvo>,解析成ResultVODefinePage(新版本已解决)

smart-doc和swagger区别比较

功能特性smart-docswagger代码侵入无注解侵入性严重集成复杂度简单,只需插件偏复杂插件支持有 gradle 和 maven 插件无插件openapi 规范支持支持 openapi 3.0完全支持 openapi 的版本CI 构建集成可在 ci 构建阶段使用maven 或者 gradle 命令启动插件生成文档不支持集中化文档中心集成已经和 torna 企业级接口文档管理平台对接不支持维护持续性值得信赖,开源后用户基础多,一直持续维护全球用户多,开源维护值得信赖接口 debug2.0.0 版本开始已经支持 debug,页面比 swagger 漂亮太多了。支持

Smart-doc 从 2.0.0 后几乎实现了 swagger ui 的功能,并且比 swagger ui 更简洁大方,也更符合国内开发者的诉求。当然 smart-doc 的功能也已经超过了 swagger 为 java 开发者提供的功能。当然 smart-doc 本身是只支持扫描代码生成 openapi 3.0 的文档的,也可以将生成的 openapi 3.0 文档导入到其他 ui 中渲染展示。

swagger 生成 离线的文档 需要借助第三方jar包实现,而 smart-doc 直接 运行 test 方法就可以直接导出 md,html,asciidoc 等格式文档。

设计思路不同,smart-doc 是基于 源码分析的,它生成api文档是通过分析JAVA源码主要是通过 注释 和 系统自带注解,来实现文档的 生成,而 swagger 是运行时 自动生成在线文档,并且 生成 测试 接口的 案例。由于他们设计思路 理念 不一样,swagger2 使用过程需要使用它定义的@API 相关注解,这样就污染了源码,代码入侵有点高,而smart -doc 就不一样了,主要是通过 注释 、解析/* / 来生成API文档的 。这样基本上没有入侵性,很自由!

swagger

  • 侵入式接口文档生成
  • 每个接口及每个实体类都需要添加注解
  • 配置复杂,需要添加依赖然后需要添加相关配置
  • 编译后自动生成接口文档
  • 需要启动后才能查看,如果配置了安全框架还需要开放相关接口

smart-doc的使用姿势

姿势一

使用maven或者gradle插件进行一键生成对应的文档格式或者命令进行生成,在这里我只展示了maven插件的使用姿势。

<plugin>
    <groupId>com.github.shalousungroupId>
    <artifactId>smart-doc-maven-pluginartifactId>
    <version>2.4.9version>
    <configuration>

        <configFile>./src/main/resources/smart-doc.jsonconfigFile>

        <projectName>测试projectName>

        <excludes>

            <exclude>com.alibaba:fastjsonexclude>
        excludes>

        <includes>

            <include>com.alibaba:fastjsoninclude>

            <include>com.baomidou:mybatis-plus-extensioninclude>

            <include>org.springframework.data:spring-data-commonsinclude>
        includes>
    configuration>
    <executions>
        <execution>

            <phase>compilephase>
            <goals>

                <goal>htmlgoal>
            goals>
        execution>
    executions>
plugin>

如果配置 <phase>clean|validate|compile|test|package|verify|install|site|deploy</phase>这些,可以在以上指令被触发时执行smart-doc文档生成

使用maven插件命令如下:

//生成html
mvn -Dfile.encoding=UTF-8 smart-doc:html
//生成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
// 生成文档推送到Torna平台
mvn -Dfile.encoding=UTF-8 smart-doc:torna-rest

// Apache Dubbo RPC文档
// Generate html
mvn -Dfile.encoding=UTF-8 smart-doc:rpc-html
// Generate markdown
mvn -Dfile.encoding=UTF-8 smart-doc:rpc-markdown
// Generate adoc
mvn -Dfile.encoding=UTF-8 smart-doc:rpc-adoc

// 生成dubbo接口文档推送到torna
mvn -Dfile.encoding=UTF-8 smart-doc:torna-rpc

使用IDE一键生成如下:

猿创征文|小而巧的API文档生成工具之smart-doc

优点:便捷,快速上手

缺点:每个服务各自指定smart-doc的配置文件smart-doc.json

姿势二

导入相关smart-doc依赖


<dependency>
    <groupId>com.github.shalousungroupId>
    <artifactId>smart-docartifactId>
    <version>2.5.1version>
dependency>

手动为每个项目引入以上jar包,可以使用smart-doc.json配置文件也可以使用smart-doc自带的 ApiConfig配置类进行手动配置。

使用单元测试测试API文档生成如下:

@Test
public void testBuilderControllersApi() {
    ApiConfig config = new ApiConfig();
    config.setServerUrl("http://localhost:8080");

    config.setAllInOne(true);

    config.setOutPath("src/main/resources/static/doc");

    config.setPackageFilters("com.***.Controller.*");

    List<ApiErrorCode> errorCodeList = new ArrayList<>();
    for (HttpCodeEnum codeEnum : HttpCodeEnum.values()) {
        ApiErrorCode errorCode = new ApiErrorCode();
        errorCode.setValue(codeEnum.getCode()).setDesc(codeEnum.getMessage());
        errorCodeList.add(errorCode);
    }

    config.setErrorCodes(errorCodeList);

    HtmlApiDocBuilder.buildApiDoc(config);
}

姿势三(公司内部推荐使用)

Q:为什么说公司内部建议使用呢?
:每个公司都会有自己的maven仓库(几乎),可以搞一些定制化的工具包,比如:日志、认证、链路、授权等。可以在工具包中加入smart-doc包进行简单开发。

可以这么做:
将smart-doc集成到工具包中,在工具包进行打包,提供给使用方,然后定制开发进行配置化管理

每个Java业务服务引入公共jar包,然后进行配置,自定义配置如下:

是否开启html生成,默认为false
smart-doc.html-enable=true
html生成路径,默认为当前服务子目录doc下
smart-doc.out-path=/doc/
接口返回对象配置
smart-doc.response-class-name=com.sparkxmedia.xplatform.sd.api.common.result.ResultVO
自定义请求头
smart-doc.request-header.username=zane
smart-doc.request-header.user_id=1
smart-doc.request-header.authorization=test
controller层包
smart-doc.package-filters=com.sparkxmedia.xplatform.sd.api.ai.controller.*,com.sparkxmedia.xplatform.sd.api.controller.*
如果使用swagger-ui替代smart-doc的html,则需配置获取openapi.json路径
springdoc.swagger-ui.url=/sd-api/doc/openapi.json

其核心代码如下:

package com.cuizb.tools.starter.config.doc;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ResourceUtils;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Slf4j
@Configuration
@EnableConfigurationProperties({ApiDocProperties.class})
public class WebMvcConfig implements WebMvcConfigurer {
    @Autowired
    private ApiDocProperties apiDocProperties;

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedHeaders("*")
                .allowedMethods("*")
                .allowedOriginPatterns("/**")
                .maxAge(3600);
    }

    @SneakyThrows
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

        String rootPath = ResourceUtils.getURL("").getPath();

        rootPath = rootPath.substring(0, rootPath.length() - 1) + apiDocProperties.getOutPath();

        String resourcesPath;
        if ("dev".equals(apiDocProperties.getProfileActive()) || "local".equals(apiDocProperties.getProfileActive())) {
            resourcesPath = "file:///" + rootPath;
        } else {
            resourcesPath = "file:///" + apiDocProperties.getOutPath();
        }

        log.info(">>>>>>>>>>>>>" + resourcesPath);

        registry
                .addResourceHandler("/doc/static/**")
                .addResourceLocations(resourcesPath);
    }

}
package com.cuizb.tools.starter.config.doc;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Configuration
@ConfigurationProperties(prefix = "smart-doc")
public class ApiDocProperties {

    @Value("${server.port}")
    private int port;

    @Value("${app.id}")
    private String appId;

    @Value("${server.servlet.context-path:}")
    private String pathFilter;

    @Value("${spring.profiles.active:dev}")
    private String profileActive;

    private boolean htmlEnable;

    private String outPath;

    private String responseClassName;

    private Map<String, String> requestHeader = new HashMap<>();

    private String packageFilters;
}


@Slf4j
@EnableConfigurationProperties({ApiDocProperties.class})
@Controller

@Profile({"dev", "local", "qa", "test", "sit", "uat"})
@RequestMapping("/doc")
public class DocController {
    @Autowired
    private ApiDocProperties apiDocProperties;

    private ApiDocConfig apiDocConfig;

    public DocController() {

    }

    @GetMapping("/openapi.json")
    @ResponseBody
    public String openapi() {
        initApiDocConfig();
        ApiConfig config = apiDocConfig.getApiConfig();

        return OpenApiBuilder.buildOpenApi(config).trim().replace(" ", "");
    }
     @GetMapping("/build")
    public String buildHtml() {
        initApiDocConfig();
        ... ...

    }
}

代码解释:

  • WebMvcConfig解决跨域以及文件映射,由开发人员决定是否使用smart-doc生成的API接口文档页面,因为有的已经使用了其他产品,可以将smart-doc生成的json同步到现有的产品,当然如果你只使用smart-doc的话,不需要配置文件映射。
  • ApiDocProperties自定义配置,开发人员只关心自己当前服务的smart-doc相关配置即可
  • DocController工具包中的uri进行资源访问,可以自定义html,openapi.json等路径。也可以自定义开发,生成json文件或者json字符串等。

当前为了适用本公司,简单的自定义了一些开发,以下是简单的配置了一些路径资源:

  • 获取openapi.json地址:http://localhost:port[/server-servlet-context-path]/doc/openapi.json
  • 构建html文件地址:http://localhost:port[/server-servlet-context-path]/doc/build
  • html接口文档地址:http://localhost:port[/server-servlet-context-path]/doc/static/index.html

如果你想使用这种的话,你可以继续研究与开发。。。

总结

可以入手使用,关键是零侵入,还支持dubbo方式(虽然我未体验使用此方式)

谢谢阅读,如果有不一样的见解,请评论说出你的观点以及见解。。。觉得不错的话,介意点个赞吗?我知道你不介意,谢谢哈。。。

一些工具特性介绍等引用smart-doc官方文档:https://smart-doc-group.github.io/#/zh-cn/start/quickstart

Original: https://www.cnblogs.com/cuizb/p/16709521.html
Author: Java技术债务
Title: 猿创征文|小而巧的API文档生成工具之smart-doc

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/715309/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • HashMap详解

    什么是HashMap容器 【1】HashMap是使用频率最高的用于映射(键值对)处理的数据类型。随着JDK(Java Developmet Kit)版本的更新,JDK1.8对Has…

    技术杂谈 2023年7月24日
    078
  • 实战模拟│企业微信机器人实时报错预警

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    技术杂谈 2023年7月11日
    077
  • python爬虫学习-爬取某个网站上的所有图片

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    技术杂谈 2023年6月21日
    084
  • 深入浅出依赖注入及其在抖音直播中的应用

    深入浅出依赖注入及其在抖音直播中的应用 https://mp.weixin.qq.com/s/Zp-OqCVVr9CbDv1Y1zWN-w Original: https://ww…

    技术杂谈 2023年5月31日
    098
  • 一致性 hash 环

    一致性 hash 环 最近做项目 做了一个分发器 ,需要 根据请求携带的参数 把请求分发到 不同的服务器上面,最终我选择使用 一致性hash 环 来实现 ,本篇 就主要讲解一下 一…

    技术杂谈 2023年7月11日
    062
  • JSON和JS对象之间的互转

    1. jQuery插件支持的转换方式 $.parseJSON( jsonstr ); //jQuery.parseJSON(jsonstr),可以将json字符串转换成json对象…

    技术杂谈 2023年5月30日
    084
  • 10 款更先进的开源命令行工具

    Linux 诞生于 1991 年,我们熟知的 ls、 cd、 ps 等命令也出生于那个年代。虽然它们都是 30 年前的产物,但是我们现在依旧每天都在用这些命令。 也许是审美疲劳又或…

    技术杂谈 2023年6月1日
    081
  • 简单了解一下pinia的结构

    随着 Vue3 的正式转正,Pinia 也渐渐火了起来。所以要更新一下自己的知识树了。这里主要是看看新的状态是什么”形态”。 状态的容器还是”r…

    技术杂谈 2023年5月31日
    098
  • 记一次Linux server偶发CPU飙升问题的跟进与解决

    进入6月后,随着一个主要功能版本api的上线,服务端的QPS翻了一倍,平时服务器的CPU使用稳定在30%上下,高峰期则在60%上下,但是偶尔会有单台机器出现持续数分钟突然飙到90%…

    技术杂谈 2023年6月21日
    091
  • 面试题目:手写一个LRU算法实现

    LFU Least Frequently Used 算法根据数据的历史访问频率来淘汰数据,其核⼼思想是”如果数据过去被访问多次,那么将来被访问的频率也更⾼”…

    技术杂谈 2023年7月11日
    083
  • hutool的json工具完成list和json之间的转换

    前言 在一次与前端对接的简单业务中,前端返回的是List 本来想直接转换为字符串类型的,但是不知道转换存储后取出的字符串是否能重新转换为List 用的是hutool提供的工具类im…

    技术杂谈 2023年5月30日
    094
  • flexible如何实现自动判断dpr?

    判断机型, 找出样本机型去适配. 比如iphone以6为样本, 宽度375px, dpr是2 Java Program! Original: https://www.cnblogs…

    技术杂谈 2023年5月31日
    0101
  • MDCFilter

    package com.common.filter; import lombok.extern.slf4j.Slf4j; import org.slf4j.MDC; import …

    技术杂谈 2023年6月1日
    086
  • 05 Java中的输入、输出流

    输入输出流 内容概括: 存在java.io包中 所有输入流都是抽象类InputStream(字节输入流)和抽象类Reader(字符输入流)的子类。 所有输出流都是抽象类Output…

    技术杂谈 2023年6月21日
    082
  • Vue之axios基础使用

    axios 简介 axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,它本身具有以下特征: 从浏览器中创建 XMLHttpRequest 从 n…

    技术杂谈 2023年5月31日
    066
  • C宏替换优先级

    宏替换仅仅是简单的替换,它不会影响运算符优先级的,比如: #define DOUBLE(x) x+x int i = DOUBLE(5)*5; printf("%d&qu…

    技术杂谈 2023年5月30日
    0108
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球