持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第 21 天,点击查看活动详情
上节课我们介绍了如何在 Umi 项目中引入 mockjs 来快速助力和完善前后端开发分离流程。
但是 lucaslz 朋友还是觉得太麻烦了,我觉得可能有同样想法的朋友还不少。
首先这里需要一个前提条件,服务端必须通过 swagger 提供给前端 api 的文档,如果你们的前端是通过 world 或者聊天窗口直接发接口文档给你的,那你用不了这个方案。
在 Umi 的项目中,我们有一个最佳实践的推荐目录 src/service 目录,用来存放与服务端发起的请求,或者说就是接口文档的前端代码翻译。
这在工作中,需要写很多重复的样板代码,虽然早起我们也通过微生成器等工具来简化了我们的工作,但是在真实的开发工作中,涉及到接口的变更,我们也需要人工的去迭代这些样板文件。
这些工作其实会站到将近四分之一的工作量。因此我们就设想着能不能通过后端模型直接生成对应的数据,甚至生成前端需要的代码。
其实早在3年前我们就意识到了这个问题,并且开始“偷懒”。我们建立了一个工具,叫做米莱狄,它能够通过 swagger 的 url 自动化生成 service 文件和 mock 文件。这很好用,但是由于那时候我们是开源社区小透明,所以知道这工具的人很少,其实在 alitajs 社区中还有很多类似好用的工具,以后有机会我会分享给更多的朋友。
今天要分享的方案,是在 ant design pro 中使用到的 openAPI 插件。
openAPI 对于后端是有一定要求的,但是工作量远远小于维护一个文档的成本,如果维护一个文档,那么每次更新完代码就需要重新编辑一遍文档。而使用 openAPI 的方式只要接入 swagger 然后做一些配置就可以生成一个界面,如果你使用的是 python 或者是 java,那么接入会变得异常简单。详细的接入步骤可以看 swagger 的官方文档。这里主要介绍前端如何使用。
后端接入完成 swagger 之后,我们可以访问 swagger 生成的文档,一般来说都是 http://localhost:8080/swagger-ui.html
,访问页面我们可以拿到一个 openAPI 的规范文件。
使用
安装插件
pnpm i @umijs/max-plugin-openapi swagger-ui-react
配置
然后在 config/config.ts
中配置 openAPI 的相关配置。
plugins: [
// ... 其他插件
// 这是当前的目录,最近正在调整这个插件,如果你这么写报错了,请访问官网查看最新用法
require.resolve("@umijs/max-plugin-openapi/dist/openapi"),
],
openAPI: {
// 这里使用服务端提供的url
schemaPath: "https://gw.alipayobjects.com/os/antfincdn/M%24jrzTTYJN/oneapi.json",
mock: true,
}
配置命令
然后在 package.json
中配置 scripts 命令。
"scripts": {
"start": "umi dev",
"openapi": "umi openapi",
"build": "cross-env ANALYZE=1 umi build"
},
执行命令
pnpm openapi
效果
执行日志如下:
> [email protected] openapi /Users/congxiaochen/Documents/umi4-course
> umi openapi
info - Using Request Plugin
Using openapi Plugin
[openAPI]: ✅ 成功生成 service 文件
[openAPI]: ✅ 生成 mock 文件成功
[openAPI]: execution complete
自动生成如下文件:
不仅仅是代码
是不是觉得很神奇了,开始心动了,但是其实这个插件给你的不仅仅是代码,还有文档,我相信有过真实开发经历的朋友,一定都遇到过一个问题,在本地连调的时候,服务端重启了,你需要等他重启,5-10分钟时最少的了。有些朋友回想说这不就是合理摸鱼时间吗?但是我觉得只有主动摸鱼才叫摸鱼,被动摸鱼,那就是“卡壳”。
这时候你就可以在开发环境中访问 /umi/plugin/openapi
路由看到接口文档页面了。
实现
1、通过 http 请求 openAPI
配置中的 schemaPath
地址。
openAPI: {
schemaPath: "https://gw.alipayobjects.com/os/antfincdn/M%24jrzTTYJN/oneapi.json",
}
2、将请求回来的参数保存在临时文件 node_modules/umi_open_api/umi-plugins_openapi.json
中。
umi-plugins_openapi.json
{
"openapi": "3.0.1",
"info": {
"version": "1.0.0"
},
"servers": [
],
"paths": {
"/api/currentUser": {
"get": {
"tags": [
"api"
],
"description": "获取当前的用户",
"operationId": "currentUser",
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CurrentUser"
}
}
}
},
"401": {
"description": "Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
}
}
}
},
"x-swagger-router-controller": "api"
}
},
"components": {
"schemas": {
}
}
}
3、生成临时的页面文件 src/.umi/plugin-openapi/openapi.tsx
import { useState } from "react";
import SwaggerUI from "swagger-ui-react";
import "swagger-ui-react/swagger-ui.css";
const App = () => {
return (<SwaggerUI url={`/umi-plugins_openapi.json`} />);
};
export default App;
4、通过中间件将 /umi-umi-plugins_openapi
映射到临时文件中
api.addBeforeMiddlewares(() => {
return [serveStatic('umi-plugins_openapi')];
});
5、为 Umi 手动添加一个可访问的路由
api.modifyRoutes((routes) => {
routes['umi/plugin/openapi'] = {
path: '/umi/plugin/openapi',
absPath: '/umi/plugin/openapi',
id: 'umi/plugin/openapi',
file: 'src/.umi/plugin-openapi/openapi.tsx',
};
return routes;
});
到此文档展示的功能完成。
6、定义 openapi 命令
api.registerCommand({
name: 'openapi',
fn: async () => {
const openAPIConfig = api.config.openAPI;
genAllFiles(openAPIConfig);
},
});
这使得我们可以通过执行 umi openapi
来执行一些 node 操作,比如上面的 genAllFiles
7、 定义 genAllFiles 函数
找到生成文件的路径,比如 mock 文件和 services 文件的等,然后根绝 swagger 的内容生成对应的文件,实现较长,这里就不贴代码了,感兴趣的朋友可以查看umi-preset-pro,这是我为 ant design pro@next 的发布,创建的一个 presets。后续里面会有其他 pro 专用的插件收录,感兴趣的朋友可以关注一下。
感谢阅读,关于 Umi 如果你有任何想了解的内容,可以多在评论区和我交流哦。