vue 自動生成swagger接口請求文件的方法
前端: vue-element-admin
后端: .net core (6.0)
找了很多自動生成的代碼的,感覺不太行,可能是我不太懂。所以自己根據(jù)swagger.json去生成了js請求文件。
后端很簡單,就不說了,只要能訪問到swagger的地址就可以,主要是前端。這個生成的比較簡單,你們可以根據(jù)自己的需求修改生成文件js里的代碼。前端代碼也參考了網(wǎng)上的一些內(nèi)容。
1.在項目目錄下新建genSwagger文件夾,然后新建autoGen.js文件
2.autoGen.js文件內(nèi)容如下,里面的內(nèi)容大部分有注釋,可以根據(jù)自己的項目情況做些修改
const fs = require('fs') const path = require('path') let apiData = {} // 訪問swagger.json的數(shù)據(jù) const http = require('http') const apiUrl = 'http://localhost:5227/swagger/v1/swagger.json' // swagger.json的地址,這里是本地的,可以替換成你的地址,有個問題是目前只能是http,https的不行,https會報一個證書錯誤 // 生成api文件的目錄 function mkdirsSync(dirname) { if (fs.existsSync(dirname)) { return true } else { if (mkdirsSync(path.dirname(dirname))) { fs.mkdirSync(dirname) return true } } } function getPath(pathUrl) { return path.resolve(__dirname, pathUrl) } let dataList = [] // 真正要處理的數(shù)據(jù) // 將swagger.json中的數(shù)據(jù)轉(zhuǎn)換成我們需要的數(shù)據(jù) function getDataList() { // 遍歷apiData.paths for (const key in apiData.paths) { let routeData = {} routeData.api = key console.log('path================ ' + key) // 遍歷apiData.paths[key] for (let key2 in apiData.paths[key]) { routeData.method = key2 console.log('methods============== ' + key2) let tag = apiData.paths[key][key2].tags[0] console.log('tag=====' + tag) routeData.controller = tag let params = apiData.paths[key][key2].parameters if (params) { routeData.bodyType = 'query' routeData.params = apiData.paths[key][key2].parameters } else { routeData.params = [] if (key2 === 'post' && key2 !== 'get') { routeData.bodyType = 'body' let requestBody = apiData.paths[key][key2].requestBody if (requestBody) { let content = requestBody.content if (content) { let applicationJson = content['application/json'] if (applicationJson) { let schema = applicationJson.schema if (schema) { let properties = schema.$ref if (properties) { let ref = properties.split('/') let refName = ref[ref.length - 1] let refData = apiData.components.schemas[refName] if (refData) { let refProperties = refData.properties if (refProperties) { for (let key3 in refProperties) { let param = {} param.name = key3 param.in = 'body' param.required = true param.schema = refProperties[key3] routeData.params.push(param) } } } } } } } } } } //遍歷apiData.paths[key][key2] for (let key3 in apiData.paths[key][key2]) { // console.log('tags===========' + key3) if (key2 === 'get') { //routeData.params = apiData.paths[key][key2][key3].parameters } //routeData.other = apiData.paths[key][key2][key3] console.log(apiData.paths[key][key2][key3]) } console.log('xxxxxxxxxxxxxxxxxxxxxxxxxxxxx') } dataList.push(routeData) } console.log(dataList) } // 獲取遠(yuǎn)程swagger.json的數(shù)據(jù) function httpGetJson(url) { return new Promise((resolve, reject) => { http.get(url, (res) => { const { statusCode } = res const contentType = res.headers['content-type'] let error if (statusCode !== 200) { error = new Error('請求失敗。\n' + `狀態(tài)碼: ${statusCode}`) } else if (!/^application\/json/.test(contentType)) { error = new Error('無效的 content-type.\n' + `期望 application/json 但獲取的是 ${contentType}`) } if (error) { console.log('error') // 消耗響應(yīng)數(shù)據(jù)以釋放內(nèi)存 console.error(error.message) res.resume() return } res.setEncoding('utf8') let rawData = '' res.on('data', (chunk) => { rawData += chunk }) res.on('end', () => { try { const parsedData = JSON.parse(rawData) resolve(parsedData) } catch (e) { reject(`錯誤: ${e.message}`) } }) }).on('error', (e) => { reject(`錯誤: ${e.message}`) }) }) } // 生成http請求js文件 async function createHttpJsFile() { console.log('start') apiData = await httpGetJson(apiUrl) getDataList() console.log(dataList) if (dataList.length === 0) { console.log('請先點擊getUsers按鈕') return } let httpJs = '' if (dataList.length > 0) { const dirPath = '/src/api-service' // dataList根據(jù)controller去重 const controllerList = [] for (let i = 0; i < dataList.length; i++) { const routeData = dataList[i] const controller = routeData.controller if (controllerList.indexOf(controller) === -1) { controllerList.push(controller) } } // 生成http請求js文件 for (let i = 0; i < controllerList.length; i++) { httpJs += `import { httpGet, httpPost } from '@/utils/http'\n` const fileName = controllerList[i] // 查找dataList里與 controllerList[i]相同的數(shù)據(jù) (同一個controller的api放在一起) const controllerDataList = dataList.filter(item => item.controller === controllerList[i]) console.log(controllerDataList) for (const data of controllerDataList) { const api = data.api // /api/user/getUserList // 取出api中最后一個斜杠后面的內(nèi)容 const apiName = api.substring(api.lastIndexOf('/') + 1) if (data.method === 'get') { httpJs += `export async function ${apiName}(` if (data.params && data.params.length > 0) { for (let i = 0; i < data.params.length; i++) { const param = data.params[i] if (i === 0) { httpJs += `${param.name}` } else { httpJs += `,${param.name}` } } } httpJs += `) {\n` httpJs += ` return await httpGet('${data.api}'` if (data.params && data.params.length > 0) { httpJs += `,{\n` for (let i = 0; i < data.params.length; i++) { const param = data.params[i] if (i === 0) { httpJs += ` ${param.name}:${param.name}` } else { httpJs += ` ,${param.name}:${param.name}` } } httpJs += ` })\n` httpJs += `}\n` } else { httpJs += `)}\n` } } else if (data.method === 'post') { // post后面帶參數(shù) if (data.params.length > 0 && data.bodyType === 'query') { httpJs += 'export async function ' + apiName + '(' for (let i = 0; i < data.params.length; i++) { const param = data.params[i] if (i === 0) { httpJs += `${param.name}` } else { httpJs += `,${param.name}` } } httpJs += `) {\n` httpJs += ` return await httpPost('${data.api}` if (data.params && data.params.length > 0) { for (let i = 0; i < data.params.length; i++) { const param = data.params[i] if (i === 0) { httpJs += `?${param.name}='+${param.name}` } else { httpJs += `+'&${param.name}='+${param.name}` } } httpJs += `)}\n` } else { httpJs += `)}\n` } } else { httpJs += 'export async function ' + apiName + '(data) {\n' httpJs += ' return await httpPost(\'' + data.api + '\',data)\n' httpJs += '}\n' } } } // 生成js文件 mkdirsSync(getPath(`..${dirPath}/`)) fs.writeFileSync(getPath(`..${dirPath}/${fileName}.js`), httpJs) httpJs = '' } console.log(httpJs) } } // 調(diào)用一下 createHttpJsFile()
3.在package.json下面的scripts節(jié)點下新增內(nèi)容:"swagger": "node genSwagger/autoGen.js"
4.在控制臺運(yùn)行 npm run swagger
5.運(yùn)行完成后,會在目錄下面看到你生成的文件
這里我只是做測試,接口較少。
上面圖片里的import其實就是很簡單的axios封裝
代碼如下:
// axios get方法 import axios from 'axios' import notification from 'element-ui/packages/notification' const baseUrl = 'https://localhost:7221' axios.defaults.timeout = 5000 axios.defaults.xsrfHeaderName = '' axios.defaults.xsrfCookieName = '' export function httpGet(url, params) { return new Promise((resolve, reject) => { axios.get(baseUrl + url, { params: params }).then(res => { resolve(res.data) }).catch(err => { reject(err.data) }) }) } // axios post方法 export function httpPost(url, params) { return new Promise((resolve, reject) => { axios.post(baseUrl + url, params).then(res => { // 攔截不是200的狀態(tài)碼 if (res.status !== 200) { notification.error('請求失敗,狀態(tài)碼:' + res.status) return } resolve(res.data) }).catch(err => { console.log(err) notification.error({ title: '錯誤', message: '請求出錯' }) reject(err.data) }) }) }
這邊完成后,就可以在頁面上調(diào)用了
目前封裝的方法可能還有點簡單,但對我來說暫時夠用了。
最后再附上swagger.json的數(shù)據(jù),就是解析這些數(shù)據(jù)生成的文件。
{ "openapi": "3.0.1", "info": { "title": "WebApplication1", "version": "1.0" }, "paths": { "/api/test/getusers": { "get": { "tags": [ "Test" ], "responses": { "200": { "description": "Success" } } } }, "/api/test/add": { "post": { "tags": [ "Test" ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/User" } }, "text/json": { "schema": { "$ref": "#/components/schemas/User" } }, "application/*+json": { "schema": { "$ref": "#/components/schemas/User" } } } }, "responses": { "200": { "description": "Success" } } } }, "/api/user/getUserList": { "get": { "tags": [ "User" ], "parameters": [ { "name": "keyWord", "in": "query", "schema": { "type": "string" } }, { "name": "pageIndex", "in": "query", "schema": { "type": "integer", "format": "int32" } }, { "name": "limit", "in": "query", "schema": { "type": "integer", "format": "int32" } } ], "responses": { "200": { "description": "Success" } } } }, "/api/user/add": { "post": { "tags": [ "User" ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/User" } }, "text/json": { "schema": { "$ref": "#/components/schemas/User" } }, "application/*+json": { "schema": { "$ref": "#/components/schemas/User" } } } }, "responses": { "200": { "description": "Success" } } } }, "/api/user/detail": { "get": { "tags": [ "User" ], "parameters": [ { "name": "id", "in": "query", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Success" } } } }, "/api/user/remove": { "post": { "tags": [ "User" ], "parameters": [ { "name": "id", "in": "query", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Success" } } } }, "/WeatherForecast": { "get": { "tags": [ "WeatherForecast" ], "operationId": "GetWeatherForecast", "responses": { "200": { "description": "Success", "content": { "text/plain": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/WeatherForecast" } } }, "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/WeatherForecast" } } }, "text/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/WeatherForecast" } } } } } } } } }, "components": { "schemas": { "User": { "type": "object", "properties": { "id": { "maxLength": 36, "minLength": 0, "type": "string", "nullable": true }, "name": { "maxLength": 50, "minLength": 0, "type": "string", "nullable": true }, "createTime": { "type": "string", "format": "date-time" } }, "additionalProperties": false }, "WeatherForecast": { "type": "object", "properties": { "date": { "type": "string", "format": "date-time" }, "temperatureC": { "type": "integer", "format": "int32" }, "temperatureF": { "type": "integer", "format": "int32", "readOnly": true }, "summary": { "type": "string", "nullable": true } }, "additionalProperties": false } } } }
到此這篇關(guān)于vue 自動生成swagger接口請求文件的文章就介紹到這了,更多相關(guān)vue swagger接口內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue-meta實現(xiàn)router動態(tài)設(shè)置meta標(biāo)簽的方法
這篇文章主要介紹了vue-meta實現(xiàn)router動態(tài)設(shè)置meta標(biāo)簽,實現(xiàn)思路非常簡單內(nèi)容包括mata標(biāo)簽的特點和mata標(biāo)簽共有兩個屬性,分別是http-equiv屬性和name屬性,本文通過實例代碼給大家詳細(xì)講解需要的朋友可以參考下2022-11-11在線使用iconfont字體圖標(biāo)的簡單實現(xiàn)
這篇文章主要介紹了在線使用iconfont字體圖標(biāo)的簡單實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-09-09vue.js中for循環(huán)如何實現(xiàn)異步方法同步執(zhí)行
這篇文章主要介紹了vue.js中for循環(huán)如何實現(xiàn)異步方法同步執(zhí)行問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-02-02解決Vue2?axios發(fā)請求報400錯誤"Error:?Request?failed?with?s
這篇文章主要給大家介紹了關(guān)于如何解決Vue2?axios發(fā)請求報400錯誤"Error:?Request?failed?with?status?code?400"的相關(guān)資料,在Vue應(yīng)用程序中我們通常會使用axios作為網(wǎng)絡(luò)請求庫,需要的朋友可以參考下2023-07-07Vue入門之?dāng)?shù)量加減運(yùn)算操作示例
這篇文章主要介紹了Vue入門之?dāng)?shù)量加減運(yùn)算操作,結(jié)合實例形式分析了vue.js基本數(shù)值運(yùn)算相關(guān)操作技巧,需要的朋友可以參考下2018-12-12Vue2和Vue3在v-for遍歷時ref獲取dom節(jié)點的區(qū)別及說明
這篇文章主要介紹了Vue2和Vue3在v-for遍歷時ref獲取dom節(jié)點的區(qū)別及說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03