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

2023-10-30

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 - Java技术债务

谁在使用smart-doc

小而巧的API文档生成工具之smart-doc - Java技术债务

smart-doc的优缺点

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

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

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

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

smart-doc和swagger区别比较

功能特性 smart-doc swagger
代码侵入 注解侵入性严重
集成复杂度 简单,只需插件 偏复杂
插件支持 有 gradle 和 maven 插件 无插件
openapi 规范支持 支持 openapi 3.0 完全支持 openapi 的版本
CI 构建集成 可在 ci 构建阶段使用maven 或者 gradle 命令启动插件生成文档 不支持
集中化文档中心集成 已经和 torna 企业级接口文档管理平台对接 不支持
维护持续性 值得信赖,开源后用户基础多,一直持续维护 全球用户多,开源维护值得信赖
接口 debug 2.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.shalousun</groupId>
    <artifactId>smart-doc-maven-plugin</artifactId>
    <version>2.4.9</version>
    <configuration>
        <!--指定生成文档的使用的配置文件,配置文件放在自己的项目中-->
        <configFile>./src/main/resources/smart-doc.json</configFile>
        <!--指定项目名称-->
        <projectName>测试</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的情况下, 使用了mybatis-plus的分页需要include所使用的源码包 -->
            <include>com.baomidou:mybatis-plus-extension</include>
            <!-- 如果配置了includes的情况下, 使用了jpa的分页需要include所使用的源码包 -->
            <include>org.springframework.data:spring-data-commons</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>

如果配置<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 - Java技术债务

优点:便捷,快速上手

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

姿势二

导入相关smart-doc依赖

<!--导入Smart-doc依赖-->
<dependency>
    <groupId>com.github.shalousun</groupId>
    <artifactId>smart-doc</artifactId>
    <version>2.5.1</version>
</dependency>

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

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

@Test
public void testBuilderControllersApi() {
    ApiConfig config = new ApiConfig();
    config.setServerUrl("http://localhost:8080");
    //当把AllInOne设置为true时,Smart-doc将会把所有接口生成到一个Markdown、HHTML或者AsciiDoc中
    config.setAllInOne(true);

    //HTML5文档,建议直接放到src/main/resources/static/doc下,Smart-doc提供一个配置常量HTML_DOC_OUT_PATH
    //源码---String HTML_DOC_OUT_PATH = "src/main/resources/static/doc";
    config.setOutPath("src/main/resources/static/doc");

    // 设置接口包扫描路径过滤,如果不配置则Smart-doc默认扫描所有的接口类
    // 配置多个报名有英文逗号隔开
    config.setPackageFilters("com.***.Controller.*");

    //设置错误错列表,遍历自己的错误码设置给Smart-doc即可
    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);
    //生成Markdown文件
    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;

/**
 * @author: Java技术债务
 * @Date: 2021/6/6 20:03
 * Describe: 跨域解决,映射生成的静态资源
 */
@Slf4j
@Configuration
@EnableConfigurationProperties({ApiDocProperties.class})
public class WebMvcConfig implements WebMvcConfigurer {
    @Autowired
    private ApiDocProperties apiDocProperties;

    /**
     * 解决跨域问题
     * @param registry
     */
    @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;

/**
 * @author Java技术债务
 * @date 2022-08-17 15:08
 * Be in awe of every code modification
 */
@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;
}

/**
 * @author Java技术债务
 * @date 2022-08-16 18:17
 * Be in awe of every code modification
 */
@Slf4j
@EnableConfigurationProperties({ApiDocProperties.class})
@Controller
//@RequestMapping("${spring.application.name}/doc")
@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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐

  • LittleFs文件系统

    小型文件系统 littlefs 简介 LittleFs设计之初的重点特性是 1 低资源消耗 2 掉电保护 3 擦写均衡 本章节重点讨论第 2 和 3 这两个特性 第 1 个特性则贯穿在整个设计过程中 后文把LittleFs简称为lfs 1
  • FaceForensics++数据集下载,FaceForensics++: Learning to Detect Manipulated Facial Images

    FaceForensics 数据集下载 FaceForensics Learning to Detect Manipulated Facial Images 0 前言 如何运行 主要是前三个超参数 不同压缩率所需的空间需求 code 0 前
  • 数据集批量打标——shell脚本批量生成文件并重命名

    shell脚本批量生成文件并重命名 最近接到一个数据集标注的任务 使用的标注工具是LabelImg 使用前配置了环境Anaconda python 3 7 Linux 并在该环境下配置了pyqt5 数据集里的图片是一段视频逐帧抽图 要求在图
  • CCNA学习笔记九 NAT地址转换及优缺点

    网络地址转换 将很多的私网地址转换成公网IP Telnet 快 可以被拦截 ssh ssl加密 安全 改变IP包头 使目的地址 源地址或两个地址在包头中被不同的地址替换 路由器会保存一个转换表 当数据包回来的时候 还原成正确的私网地址 NA
  • LED数码管数字数据集

    LED数码管数字数据集 结合百度OCR取得很好效果 数据集结合百度的OCR百度的OCR https gitee com paddlepaddle PaddleOCR tree release 2 1 程序对应数据集训练进行目标检测识别 数据
  • 在github上托管属于自己的网页

    文章目录 前言 一 配置github 1 建立新的仓库 repository 二 配置git 1 git与github连接 2 测试git与github的连接 3 通过git上传 删除github仓库中的文件 4 网页显示 5 更换域名 总
  • Anaconda安装、源配置、虚拟环境搭建、及Python常用软件安装详解(详细教程)

    首先先介绍一下各种安装软件的基本介绍和常见命令 基本介绍 Anaconda 是可以便捷获取包且对包能够进行管理 同时对环境可以统一管理的发行版本 Anaconda包含了conda Python在内的超过180个科学包及其依赖项 conda是
  • 山东大学软件学院软件项目管理复习

    考前整理的复习题 有一些考试考到了 分享给下一级吧 1 项目目标的制约因素 项目范围 成本 进度计划 客户满意度 三个约束 范围 成本 时间 项目范围是为使客户满意必须做的工作 成本是完成项目所需要的费用 进度计划安排每项任务的起始时间和所
  • pre标签显示服务器端txt文档,区域设计pre显示标签pre

    区域设计pre显示标签pre 内容精选 换一换 在现场讲解汇报 实时监控等场景下 为了获得更好的演示效果 通常需要将态势感知服务的分析结果展示在大型屏幕上 如果只是单纯将控制台界面放大显示 视觉效果并不是很理想 此时可以利用综合大屏 展示专
  • Java并发修改异常ConcurrentModificationException

    import java util ArrayList import java util Iterator import java util ListIterator public class ConcurrentModificationEx
  • A complete log of this run can be found in:

    npm run dev npm ERR code ENOENT npm ERR syscall open npm ERR path C Users Administrator Desktop 项目名 package json npm ERR
  • 什么是设计模式?程序员如何学好设计模式?

    前几天 我给大家介绍了算法和数据结构的基础知识 后来又有小伙伴私信问我 小灰 你能不能也讲一讲设计模式的相关知识 没问题 对于程序员来说 设计模式也是必须要掌握的一项核心知识 我今天就来给大家重点讲一讲 编程的痛点 那么 到底什么是设计模式
  • 上海市“星光计划”职业院校技能大赛 网络安全竞赛试题任务书

    2023上海市 星光计划 职业院校技能大赛 网络安全竞赛试题任务书 2023上海市 星光计划 职业院校技能大赛 网络安全竞赛试题任务书 A模块基础设施设置 安全加固 200分 A 1 登录安全加固 A 2 Web安全加固 Web A 3 流
  • linux2.4内核模块隐藏,Linux环境下的高级隐藏技术

    摘要 本文深入分析了Linux环境下文件 进程及模块的高级隐藏技术 其中包括 Linux可卸载模块编程技术 修改内存映象直接对系统调用进行修改技术 通过虚拟文件系统proc隐藏特定进程的技术 隐藏技术在计算机系统安全中应用十分广泛 尤其是在
  • 学习笔记 JavaScript ES6 Reflect

    学习内容 将Object属于语言内部的方法放到Reflect上 修改某些Object方法的返回结果 让其变得更合理 让Object操作变成函数行为 Reflect对象的方法与Proxy对象的方法相辅相成 将Object属于语言内部的方法放到
  • Jenkins + 云效 前后端项目自动化部署

    环境安装 创建目录 后续下载的内容 放在里边方便管理 cd mkdir docker cd docker mkdir maven mkdir jenkins mkdir java mkdir registry 宝塔 不在赘述 前往官网有安装
  • 爬取数据是违法的吗_网络爬虫违法吗?

    Web爬取 也称为Web抓取 数据抓取或爬虫 是一种计算机程序技术 用于从网站上抓取大量数据 并将其处理为结构化数据 Web抓取是常用的 基本上 网页抓取是互联网的功能 例如 SEO需要创建站点地图并授予其权限 让Google对其网站进行抓
  • R learning 十八讲 0018-R语言绘图基础

    0018 R语言绘图基础 2020 07 29更新 使用代码块 看起来更方便 更改了第6节 这次不介绍如ggplot2等绘图包 只记录一些R基础就能实现的东西 跟着我爪子敲一遍 相信你会有收获 有用的话请点赞收藏 O 嗷 能点个大大的关注就
  • vue2中使用axios,以及axios拦截器的配置

    目录 一 vue2项目中如何实现异步请求 1 axios 是一个基于Promise的网络请求库 既可以在node js 服务器端 使用 也可以在浏览器端使用 2 vue中的使用方法 2 引用方法 A 原生的方式 不推荐使用 B 在项目的ma
  • 猿创征文|小而巧的API文档生成工具之smart-doc

    文章目录 smart doc介绍 smart doc特性 smart doc的最佳搭档 谁在使用smart doc smart doc的优缺点 smart doc和swagger区别比较 smart doc的使用姿势 姿势一 姿势二 姿势三