smart doc 作为一个接口文档生成工具,可以根据代码的java doc注释,生成接口文档。同时已经对接到Torna接口平台。
鉴于大家用的接口平台五花八门,Torna的功能可能不符合大家的需求,研究下是否可以基于smart doc,拓展功能对接其他接口平台
根据插件命令的名称,从 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
转换成我们需要的数据结构,融入到其他接口平台中去。不过这过程需要其他接口平台也提供这种接口推送,或者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,有需要的话创建自定义的插件。