[前后端分离]Mock Restful Api工程化简单实现
1.前言
在前后端分离开发过程中,为了避免前端开发完成而后端接口还未跟上进度时,往往会用mock来模拟接口数据。可以选择用第三方mock平台,也可以选择自己搭建mock服务。这里我将给出一个简易的mock restful api服务源代码(node.js实现)。
更多mock相关内容参考mock.js官方http://mockjs.com/
另外,推荐自己搭一个easy mock,可以很方便地模拟后端数据,非常好用~
2.代码实现
2.1 目录结构
2.2 包依赖:package.json
{
"name": "mock-server",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"express": "^4.16.4",
"mockjs": "^1.0.1-beta3",
"nodemon": "^1.18.10"
}
}
2.3 mock-server.js代码部分(服务器主要逻辑)
const path = require('path') // 引入path模块
const fs = require('fs') // 引入fs模块
const express = require('express') // 引入express模块
const bodyParser = require('body-parser') // body-parser中间件解析post请求
const app = express() // 实例化express
const mockData = {} // mock数据
// www-form-urlencoded
app.use(bodyParser.urlencoded({
extended: true
}))
// // application/json
// app.use(bodyParser.json());
// 判断是否是文件夹
function isFileExists (filePath) {
const stat = fs.lstatSync(filePath)
return stat.isDirectory()
}
// 读取mock目录下的所有文件,组装mockData
function readMockDir (dir) {
fs.readdirSync(dir).forEach(function (file) {
let _path = path.join(dir + '/' + file)
if (isFileExists(_path)) {
readMockDir(_path)
} else {
Object.assign(mockData, require(_path))
}
})
}
readMockDir(path.join(__dirname + '/mock'))
// 遍历mockData对象,
// 获取每个接口的路径(url)和方法(method),
// 并通过express调用mock数据
for (let key in mockData) {
let _key = key.replace(/(^\s*)|(\s*$)/g, '')
let _method = 'get'
let _url = _key.replace(/^(get|post|put|delete)\s*/i, function (rs, $1) {
_method = $1.toLowerCase()
return ''
})
app[_method](_url, mockData[key])
}
// 监听8090端口
app.listen('8090', function () {
console.log('MOCK Server is running at http://localhost:8090')
})
2.4 mock-start.js(入口,开启守护进程)
const path = require('path') // 引入path模块
const fs = require('fs') // 引入fs模块
const express = require('express') // 引入express模块
const bodyParser = require('body-parser') // body-parser中间件解析post请求
const app = express() // 实例化express
const mockData = {} // mock数据
// www-form-urlencoded
app.use(bodyParser.urlencoded({
extended: true
}))
// // application/json
// app.use(bodyParser.json());
// 判断是否是文件夹
function isFileExists (filePath) {
const stat = fs.lstatSync(filePath)
return stat.isDirectory()
}
// 读取mock目录下的所有文件,组装mockData
function readMockDir (dir) {
fs.readdirSync(dir).forEach(function (file) {
let _path = path.join(dir + '/' + file)
if (isFileExists(_path)) {
readMockDir(_path)
} else {
Object.assign(mockData, require(_path))
}
})
}
readMockDir(path.join(__dirname + '/mock'))
// 遍历mockData对象,
// 获取每个接口的路径(url)和方法(method),
// 并通过express调用mock数据
for (let key in mockData) {
let _key = key.replace(/(^\s*)|(\s*$)/g, '')
let _method = 'get'
let _url = _key.replace(/^(get|post|put|delete)\s*/i, function (rs, $1) {
_method = $1.toLowerCase()
return ''
})
app[_method](_url, mockData[key])
}
// 监听8090端口
app.listen('8090', function () {
console.log('MOCK Server is running at http://localhost:8090')
})
2.5 一个测试实例
mock/api1/api1.js
const Mock = require('mockjs')
let getApi1Data = (req) => {
// console.log(req.query);
return Mock.mock({
'data|1-9': [{
'name|5-8': /[a-zA-Z]/,
'id|+1': 1,
'value|0-500': 0,
'age|1-100': 1
}]
})
}
module.exports = {
[`GET /api1`] (req, res) {
res.status(200).json(getApi1Data(req))
}
}
2.6 启动命令
(在mock-server目录下) npm install (安装依赖) node mock-start.js (开启服务)