smart doc:自动生成接口文档拓展

smart doc 作为一个接口文档生成工具,可以根据代码的java doc注释,生成接口文档。同时已经对接到Torna接口平台。

鉴于大家用的接口平台五花八门,Torna的功能可能不符合大家的需求,研究下是否可以基于smart doc,拓展功能对接其他接口平台

源码功能分析

定位Torna功能源码

根据插件命令的名称,从 smart-doc-maven-plugin 项目找到 torna-rest 的maven插件命令定义Mojo类 TornaRestMojo

以下即为命令执行入口代码

@Execute(phase = LifecyclePhase.COMPILE)
@Mojo(name = MojoConstants.TORNA_REST_MOJO, requiresDependencyResolution = ResolutionScope.COMPILE)
public class TornaRestMojo extends BaseDocsGeneratorMojo {

    @Override
    public void executeMojo(ApiConfig apiConfig, JavaProjectBuilder javaProjectBuilder) {
        try {
            TornaBuilder.buildApiDoc(apiConfig, javaProjectBuilder);
        } catch (Exception e) {
            getLog().error(e);
        }
    }
}

这里可以看到实现入口为 TornaBuilder.buildApiDoc, 继续跟踪到 smart-doc 项目下的 TornaBuilder

流程主要分为两步:通过buildApiDoc 生成接口文档,再转换数据结构,根据接口配置,推送到Torna

    /**
     * Only for smart-doc maven plugin and gradle plugin.
     *
     * @param config             ApiConfig
     * @param javaProjectBuilder ProjectDocConfigBuilder
     */
    public static void buildApiDoc(ApiConfig config, JavaProjectBuilder javaProjectBuilder) {
        config.setParamsDataToTree(true);
        DocBuilderTemplate builderTemplate = new DocBuilderTemplate();
        builderTemplate.checkAndInit(config, true);
        ProjectDocConfigBuilder configBuilder = new ProjectDocConfigBuilder(config, javaProjectBuilder);
        IDocBuildTemplate docBuildTemplate = BuildTemplateFactory.getDocBuildTemplate(config.getFramework());
        List<ApiDoc> apiDocList = docBuildTemplate.getApiData(configBuilder);
        apiDocList = docBuildTemplate.handleApiGroup(apiDocList, config);
        // 将数据转换为Torna的接口格式 并推送到Torna去
        buildTorna(apiDocList, config, javaProjectBuilder);
    }

文档生成部分目前符合我们的需求,看看推送部分,也只是简单的层级数据转换和接口请求。

    /**
     * build torna Data
     *
     * @param apiDocs   apiData
     * @param apiConfig ApiConfig
     * @param builder   JavaProjectBuilder
     */
    public static void buildTorna(List<ApiDoc> apiDocs, ApiConfig apiConfig, JavaProjectBuilder builder) {
        TornaApi tornaApi = new TornaApi();
        tornaApi.setAuthor(StringUtil.isEmpty(apiConfig.getAuthor()) ? System.getProperty("user.name") : apiConfig.getAuthor());
        tornaApi.setIsReplace((apiConfig.getReplace() == null || apiConfig.getReplace()) ? 1 : 0);
        Apis api;
        List<Apis> groupApiList = new ArrayList<>();
        //Convert ApiDoc to Apis
        for (ApiDoc groupApi : apiDocs) {
            List<Apis> apisList = new ArrayList<>();
            List<ApiDoc> childrenApiDocs = groupApi.getChildrenApiDocs();
            for (ApiDoc a : childrenApiDocs) {
                api = new Apis();
                api.setName(StringUtils.isBlank(a.getDesc()) ? a.getName() : a.getDesc());
                api.setItems(buildApis(a.getList(), TornaUtil.setDebugEnv(apiConfig, tornaApi)));
                api.setIsFolder(TornaConstants.YES);
                api.setAuthor(a.getAuthor());
                api.setOrderIndex(a.getOrder());
                apisList.add(api);
            }
            api = new Apis();
            api.setName(StringUtils.isBlank(groupApi.getDesc()) ? groupApi.getName() : groupApi.getDesc());
            api.setAuthor(tornaApi.getAuthor());
            api.setOrderIndex(groupApi.getOrder());
            api.setIsFolder(TornaConstants.YES);
            api.setItems(apisList);
            groupApiList.add(api);

        }
        tornaApi.setCommonErrorCodes(buildErrorCode(apiConfig, builder));
        // delete default group when only default group
        tornaApi.setApis(groupApiList.size() == 1 ? groupApiList.get(0).getItems() : groupApiList);
        //Build push document information
        Map<String, String> requestJson = TornaConstants.buildParams(PUSH, new Gson().toJson(tornaApi), apiConfig);
        //Push dictionary information
        Map<String, Object> dicMap = new HashMap<>(2);
        List<TornaDic> docDicts = TornaUtil.buildTornaDic(DocUtil.buildDictionary(apiConfig, builder));
        if (CollectionUtil.isNotEmpty(docDicts)) {
            dicMap.put("enums", docDicts);
            Map<String, String> dicRequestJson = TornaConstants.buildParams(ENUM_PUSH, new Gson().toJson(dicMap), apiConfig);
            String dicResponseMsg = OkHttp3Util.syncPostJson(apiConfig.getOpenUrl(), new Gson().toJson(dicRequestJson));
            TornaUtil.printDebugInfo(apiConfig, dicResponseMsg, dicRequestJson, ENUM_PUSH);
        }
        //Get the response result
        String responseMsg = OkHttp3Util.syncPostJson(apiConfig.getOpenUrl(), new Gson().toJson(requestJson));

        //Print the log of pushing documents to Torna
        TornaUtil.printDebugInfo(apiConfig, responseMsg, requestJson, PUSH);

    }

最后结论

我们的可以完全复用接口文档生成的部分代码,然后将 List apiDocList 转换成我们需要的数据结构,融入到其他接口平台中去。不过这过程需要其他接口平台也提供这种接口推送,或者json及其他形式的数据导入。

只需要模仿TornaBuilder 进行拓展实现

以下为实现示例:

/**
 * 自定义文档生成接口推送
 *
 * @author azhuzhu 2022/9/20 15:13
 */
@Slf4j
public class CustomizeBuilder {

    /**
     * build controller api
     *
     * @param config config
     */
    public static void buildApiDoc(ApiConfig config) {
        JavaProjectBuilder javaProjectBuilder = JavaProjectBuilderHelper.create();
        buildApiDoc(config, javaProjectBuilder);
    }


    /**
     * Only for smart-doc maven plugin and gradle plugin.
     *
     * @param config             ApiConfig
     * @param javaProjectBuilder ProjectDocConfigBuilder
     */
    public static void buildApiDoc(ApiConfig config, JavaProjectBuilder javaProjectBuilder) {
        // 文档结构化数据生成部分完全复用
        config.setParamsDataToTree(true);
        DocBuilderTemplate builderTemplate = new DocBuilderTemplate();
        builderTemplate.checkAndInit(config, true);
        ProjectDocConfigBuilder configBuilder = new ProjectDocConfigBuilder(config, javaProjectBuilder);
        IDocBuildTemplate docBuildTemplate = BuildTemplateFactory.getDocBuildTemplate(config.getFramework());
        List<ApiDoc> apiDocList = docBuildTemplate.getApiData(configBuilder);
        apiDocList = docBuildTemplate.handleApiGroup(apiDocList, config);
        // 将List转换为对应的接口平台的对接接口数据格式,并推送过去 配置的读取方式可以自行拓展
        customizeBuild(apiDocList, config, javaProjectBuilder);
    }

    private static void customizeBuild(List<ApiDoc> apiDocs, ApiConfig apiConfig, JavaProjectBuilder builder) {
        String bodyJson = buildBodyJson(apiDocs, apiConfig, builder);
        String responseMsg = OkHttp3Util.syncPostJson(apiConfig.getOpenUrl(), bodyJson);
        log.debug(responseMsg);
    }

    private static String buildBodyJson(List<ApiDoc> apiDocs, ApiConfig apiConfig, JavaProjectBuilder builder) {
        // TODO: 实现数据结构的转换 返回Json
        return "";
    }

}

新建一个项目,引入smart-doc-maven-plugin 作为依赖,如上面代码所示实现自定义的builder,有需要的话创建自定义的插件。

你可能感兴趣的:(代码笔记,java)