前后端对接时,步骤一般如下:
1、打开接口文档
2、定位到具体的接口
3、将接口复制
4、打开前端api.js文件
5、将接口封装为前端需要的格式
假设一个项目有1000个接口,那么就需要执行1000次上述步骤。
如果把这种重复的工作自动化,让计算机去执行上述步骤。就可以很大程度提高开发效率、减少重复不必要工作。
另外,自动生成的api文件也更加便于维护,开发人员不需要过多关注api.js文件,当后端接口有更新时,只需要通过指令更新api.js即可。
api自动生成实现:
思路:
1、项目接口文档采用 swagger 生成
2、前端通过node.js的https模块,发起请求,获取接口文档的swagger.json
3、前端将获取到的swagger.json格式化处理,封装为前端api需要的格式
4、前端通过node.js的fs模块,向项目指定目录写入api.js文件
code:
新建api.js(实现api自动生成功能)
"use strict"
const fs = require('fs')
const https = require('https')
const config = require('../config.js')
/**
* 自动化生成api
* @param {String} tagname x-tagname 获取某一个模块下数据
* @param {String} filename 生成js文件名称
*/
const createData = (tagname = 'all', filename = 'api') => {
// 1. 调用接口,获取swagger response
https.get(config.apiURL, res => {
let list = []
res.on('data', chunk => {
list.push(chunk)
})
res.on('end', () => {
const swagger = JSON.parse(Buffer.concat(list).toString())
// 2. 格式化api数据结构
const apis = _getAPIS(swagger.paths, tagname)
// 3. 生成api模板数据
let text = `import request from '@/utils/request'`
text += apis.reduce((prev, current) => {
// 注释
let zhushi = current.description || current.summary
// 函数名称
let funName = current.operationId
// 函数url
let url = current.url.replace(/{
/g, '${')
// 请求方法
let method = current.method
// 形参 、请求体
let arg = new String(), body = new Array()
if (current.parameters) {
// 获取当前请求类型
let isGET = current.parameters.some(item => item.in === 'query')
let isPOST = method === 'post' || current.parameters.some(item => item.in === 'body' || item.in === 'formData')
// 形参
let path = current.parameters.filter(item => item.in === 'path').map(item => item.name)
// 如果是post请求,形参中添加data;如果是get请求,形参中增加params
isPOST ? arg += 'data' : isGET ? arg += 'params' : ''
// 形参中其余参数添加
arg += path.reduce((prev, cur, index) => prev += `${
arg.length ? ', ' : ''}${
cur}`, '')
// 请求体
body = isPOST ? 'data' : isGET ? 'params' : ''
}
// 返回文本内容
return prev +=
`
// ${
zhushi}
export function ${
funName}(${
arg}) {
return request({
url: \`${
url}\`,
method: \`${
method}\`,
${
body}
})
}`
}, '')
// 4. 文件写入
fs.writeFile(`./src/api/${
filename}.js`, text, function(err) {
if (err) {
return console.log('文件写入失败' + err.message)
} else {
console.log('文件写入成功!')
}
})
})
}).on('error', err => {
console.log('Https Error: ', err.message)
})
}
/**
* 接口返回数据转换为前端生成api数据结构
* @param {Object} source 接口返回数据
* @param {String} tagname tagname 获取某一个模块下数据
*/
const _getAPIS = (source, tagname) => {
let result = new Array()
for (let key in source) {
for (let k in source[key]) {
if (source[key][k].tags[0] === tagname || tagname === 'all') {
let api = {
...source[key][k] }
api.method = k
api.url = key
result.push(api)
}
}
}
return result
}
// 调用
createData(config.apiConfig.tagname, config.apiConfig.filename)
config.js中配置:接口文档地址,api自动生成配置
// 项目初始化数据
module.exports = {
// 接口文档地址
apiURL: 'https://账号:密码@test.com.cn/v2/api-docs?group=2.X版本',
// 自动生成api 的菜单
apiConfig: {
tagname: undefined, // 菜单名称,传undefined默认生成全部,菜单名称对应swagger文档上目录结构
filename: undefined, // 生成js文件名称,传undefined默认为api.js
}
}
项目package.json中定义运行脚本命令,执行指令 npm run api 在指定目录下生成最终的api.js
"api": "node src/utils/api.js"