- 作者:老汪软件技巧
- 发表时间:2024-10-13 17:02
- 浏览量:
一、前言
开发了个Mock CLI工具,助力开发速度提升一倍,欢迎使用和点赞:
支持能力
在开发过程中,也遇到了一些难点,做一下复盘
二、实现原理图1、原理图
2、原理描述三、项目实战1、配置命令行参数
首先我们配置mock命令,设定参数
type: 分别代表API类型,这里写一下Restful风格的实现思路
port: 服务启动的端口
配置package.json
{
"main": "index.js",
"files": [
"bin",
"command",
"public",
"utils",
"index.js",
"package.json",
"server.js",
"README.md"
],
"type": "module",
"bin": {
"dev-mock-cli": "./bin/index.js"
}
}
入口文件index.js
必须添加 #!/usr/bin/env node,否则无法执行
#!/usr/bin/env node
class MockServer {
constructor(config) {
this.config = config;
// 初始化配置
}
// 启动服务器
async start() {
// 判断当前要使用的端口是否被占用
const newPort = await getIdlePort(this.port);
// 启动服务器
const app = express();
app.use(express.urlencoded({ extended: true }));
app.use(express.json({ limit: '50mb' }));
// 通用中间件
app.all('*', cors);
app.all('*', timeoutSetting);
// 根据类型加载模块
const loadModule = this.type === 'action' ? action : restful;
loadModule({ app, filePath: this.filePath, config: this.config });
this.startServer(app);
}
// 启动Express服务器并打印启动日志
startServer(app) {
app.listen(this.port, () => logServerStart(this.port, this.type));
}
}
export default MockServer;
上面的做了三件事:
2、加载restful风格API逻辑
const restful = async ({ app, filePath, config }) => {
const { proxyApiUrl, swaggerApi=[] } = config;
// 如果没有文件,新建example
checkFileExist(filePath, true)
const apiList = getAllAPIPath(filePath);
// 获取本地所有的path,生成本地代理
app.all(apiList, async (req, res) => {
const url = req.path;
checkFileExistsAndRespond(url, filePath, req, res);
});
await fetchAndCreateRoutes({app, swaggerApi});
// 没有本地mock,则读取远程接口
if (proxyApiUrl) {
const proxyMiddleware = createProxyMiddleware({
target: proxyApiUrl,
changeOrigin: true,
})
app.use('*', proxyMiddleware);
}
};
export default restful;
上面实现了几个方法
3、检查、生成Mock数据
原理:我们以目录为api请求路径,以文件名为请求方法。
不存在路由参数的请求:
存在路由参数的请求:
4、根据swagger json数据生成API返回数据
// 生成 Mock 值的示例函数
const generateMockValue = (schema, openAPIDoc) => {
if (schema.$ref) {
// 解析 $ref 并递归处理
const resolvedSchema = resolveRef(schema.$ref, openAPIDoc);
return generateMockValue(resolvedSchema, openAPIDoc);
}
switch (schema.type) {
case 'string':
return Mock.mock('@string(5, 10)');
case 'number':
return Mock.mock('@integer(0, 1)');
case 'integer':
return Mock.mock('@integer(0, 1)');
case 'boolean':
return true;
case 'array':
return [generateMockValue(schema.items, openAPIDoc)];
case 'object':
const mockObject = {};
for (const [key, value] of Object.entries(schema.properties)) {
mockObject[key] = generateMockValue(value, openAPIDoc);
}
return mockObject;
default:
return null;
}
};
这里我们可以根据谁类型生成对应的mock数据,也可以通过配置文件来自定义生成规则。要注意的是swagger2.x和3.x的字段有些不同,需要做好不同情况的适配。
5、自动构建Docker镜像
通过Github构建不同的Docker镜像,发送Docker hub。
完成后发现启动这个API服务后,可以通过docker处理,这样也方便随时使用,镜像适配的平台不同,我们通过docker/build-push-action@v5,来配置platforms实现多个平台镜像的构建,然后通过Action推送到Docker hub
# 构建多平台镜像
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: |
${{ secrets.DOCKER_USERNAME }}/dev-mock-cli:latest
四、总结
对于大部分mock来说,复杂的配置是不需要的,一个简单的服务,然后根据文档返回模拟数据,方便前端调试即可。