Swagger3携手Umi/OpenApi:轻松驾驭自动化,后端接口秒级生成!
引言
在鱼皮开发的AI答题应用平台时,我提出过这样一个疑问:如果Swagger的接口文档中如果使用中文注释接口,那么这个umi/OpenApi是否还能正常生成代码? 答案是有点差距

像上图,接口文档的参数不明确,没有注释,左侧的接口也是英文,这样子前端对接起来感觉看起来也不是通俗易懂,再看看生成的接口文件:

全是英文,没有中文注释。我想生成的效果是:


所以接下来要说的就是如何配置能够生成带有中文参数的接口文件!
使用技术
后端
这里使用的新版本Swagger3 想着用新不用旧,在新版本上踩踩坑
官网:https://doc.xiaominfo.com/docs/quick-start
▼xml复制代码<dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-openapi3-spring-boot-starter</artifactId> <version>4.4.0</version> </dependency>
配置文件:
▼yml复制代码--- #################### swagger 相关配置 #################### # 配置springdoc-openapi的相关属性 springdoc: # 配置Swagger-UI的相关属性 swagger-ui: # 设置Swagger-UI的访问路径 path: /swagger-ui.html # 按字母表顺序对标签进行排序 tags-sorter: alpha # 按字母表顺序对操作进行排序 operations-sorter: alpha # 配置API文档的相关属性 api-docs: # 设置API文档的访问路径 path: /v3/api-docs # knife4j的增强配置,不需要增强可以不配 knife4j: enable: true setting: language: zh_cn # 设置语言为中文 enable-footer: false enable-footer-custom: true footer-custom-content: Apache License 2.0 | Copyright 2024-[codeZhang](https://github.com/XiaoZhangCode) enable-filter-multipart-apis: true
前端
生成的插件还是鱼皮在项目中常用的@umi/openapi插件
官网:https://www.npmjs.com/package/@umijs/openapi
AI答题应用平台用的Vue3
安装命令:npm i --save-dev @umijs/openapi
在 package.json 的 script 中添加 api: "openapi": "ts-node openapi.config.ts",生成api
ps: 倘若运行错误将api: "openapi": "ts-node openapi.config.ts改成api: "openapi": "node openapi.config.ts
需要在项目根目录下新建openapi.config.ts
▼javascript复制代码// eslint-disable-next-line @typescript-eslint/no-var-requires const { generateService } = require("@umijs/openapi"); generateService({ requestLibPath: "import request from '@/request'", schemaPath: "http://localhost:8101/api/v3/api-docs" // 写项目实际的接口doc地址, serversPath: "./src", });
最后npm run openapi即可生成
实现效果
接口文档是这样的:

而生成出来的效果是这样的

发现左侧的文件名称中文变成了拼音
如果说不介意这个拼音的话,那么这样就可以直接用了
解决文件名称拼音
官网给出一个自定义hook可以自己定义文件名称

我们这里把官网源码clone下来,
查看下这个方法是在什么时候调用的,能够回调回来哪些信息
在源码中我们可以找到示例代码,以及如图


回到我们AI答题应用平台中,我们可以照猫画虎,完成如下配置
▼javascript复制代码// eslint-disable-next-line @typescript-eslint/no-var-requires const { generateService } = require("@umijs/openapi"); generateService({ requestLibPath: "import request from '@/request'", schemaPath: "http://localhost:8101/api/v3/api-docs", serversPath: "./src", hook: { //@ts-ignore customFileNames: (operationObject, apiPath) => { const operationId = operationObject.operationId; if (!operationId) { // @ts-ignore console.warn("[Warning] no operationId", apiPath); return; } const res = operationId.split("_"); if (res.length > 1) { res.shift(); if (res.length > 2) { // @ts-ignore console.warn("[Warning] operationId has more than 2 part", apiPath); } return [res.join("_")]; } else { const controllerName = (res || [])[0]; if (controllerName) { return [controllerName]; } return; } }, }, });
再运行看下效果!

这里将每个方法全部都生成了一个文件,这才多少接口,就生成这么多文件,当然如果有鱼友不介意,这样也是可直接使用的
但是我这里还是想改成和之前一样,一个controller中的代码是一个文件,那么这里就需要看看他这个钩子回调回来传给我们哪些参数了
我们直接搜索Service找到这个js进入

解释下,在这个黄色框中,将文件根据tags分组 最后生成成文件 红色框是由中文变成英文的转换!

在下面这个图中,会读取到我们配置文件的hook中的自定义钩子函数

然后我们在251行打上断点,运行openApi

可以看到传入了三个参数:operationObject, p, method
operationObject这个对象就是读取后端接口地址读到的数据,p是这个接口的path路径,最后一个顾名思义就是方法的类型,我们这里往下看可以知道,他是根据这里的tags来进行方法分组然后生成的!

下述红色框将这里的中文变成了拼音,点进去

在这个resolveTypeName中变成了拼音,那么就是说我们如果给这个tags自行设置,那么生成出来的文件名称就是可以自定义了,于是我们先修改后端接口文档的@Tag中的name属性

变成如下图所示效果 使用-来分割想要生成的文件名称

修改前端配置文件,将hook中的自定义文件名称改成如下:
也就是我们将tags取出来,然后根据-分割,然后返回英文名称!
▼javascript复制代码customFileNames: (operationObject, apiPath) => { const tags = operationObject.tags[0]; if (!tags) { // @ts-ignore console.warn("[Warning] no tags", apiPath); return; } const res = tags.split("-"); if (res.length > 1) { res.shift(); if (res.length > 2) { // @ts-ignore console.warn("[Warning] tags has more than 2 part", apiPath); } return [res.join("_")]; } else { const controllerName = (res || [])[0]; if (controllerName) { return [controllerName]; } return; } },
试试效果

这样子就生成成功啦!
