前端根据openapi+swagger生成接口方法

@umijs/openapi方式

依赖安装:

npm i @umijs/openapi ts-node -D
npm i umi-request

openapi配置:

在项目根目录新建 openapi.config.js 添加以下内容

const { generateService } = require('@umijs/openapi')

generateService({
  schemaPath: 'http://xxx.com/springdoc/api-docs', // 可以是.json文件,也可以是远程json地址
  serversPath: './src/servers',
})

vite配置:

export default defineConfig({
  server: {
    proxy: {
      '^/api/': {
        target: 'http://xxx.com',
        changeOrigin: true
      },
    }
  },
}

package脚本配置:

{
  "scripts": {
    "openapi": "ts-node openapi.config.ts"
  }
}

运行命令生成文件:

npm run openapi

image.webp

因为 tsconfig.app.json 已经包含了 src 目录下的所有文件,所以不用再到 env.d.ts 中添加引用 /// <reference types="./src/servers/api/typings" /> 了。

生成的接口文件修改:

因为生成的接口文档是通过 umi 导入的 request,但在 vite + typescript 环境中会提示 request 不在 umi 的导出模块里,所以这块需要修改掉,单独使用 umi-request 来处理接口请求,umi-request 结合了 fetchaxios 的特性进行封装,文件小且使用方便。

import { request } from 'umi'

修改成

import request from 'umi-request'

批量替换,在项目根目录新建一个 openapi.replace.bat 文件,内容如下:

@echo off
chcp 65001 > nul

setlocal enabledelayedexpansion

set "old_text=import { request } from 'umi';"
set "new_text=import request from 'umi-request';"

set "file_pattern=src/servers/api/*.ts"

for %%f in (%file_pattern%) do (
    set "old_file=%%~nf%%~xf"
    set "new_file=%%~nf_output%%~xf"

    set "input_file=src/servers/api/%%~nf%%~xf"
    set "output_file=src/servers/api/%%~nf_output%%~xf"

    (for /f "usebackq delims=" %%a in (!input_file!) do (
        set "line=%%a"
        set "line=!line:%old_text%=%new_text%!"
        echo(!line!
    )) > !output_file!

    (for /f "usebackq delims=" %%a in (!output_file!) do (
        set "line=%%a"
        set "line=!line!"
        echo(!line!
    )) > !input_file!

    del "%cd%\src\servers\api\%%~nf_output%%~xf"
)

修改 package.json

{
  "scripts": {
    "openapi-create": "ts-node openapi.config.ts",
    "openapi-replace": "openapi.replace.bat",
    "openapi": "npm run openapi-create && npm run openapi-replace"
  }
}

运行命令

npm run openapi

页面中使用:

import { getUserList } from '@/servers/api/xxx'

getUserList()

swagger-typescript-api方式

依赖安装:

npm i vite swagger-typescript-api vite-plugin-swagger-typescript-api -D
npm i axios

vite配置:

vite.config.js

// 在 vite.config.ts 文件中添加如下配置
import { defineConfig } from 'vite'
import { vitePluginSwaggerTypescriptApi } from 'vite-plugin-swagger-typescript-api'

// vite 相关配置请参考 https://vitejs.dev/config/
export default defineConfig({
  server: {
    proxy: {
      '^/api/': {
        target: 'http://xxx.com',
        changeOrigin: true
      },
    }
  },
  plugins: [
    vitePluginSwaggerTypescriptApi({ // swagger-typescript-api 的配置,具体可参考 https://github.com/acacode/swagger-typescript-api
      name: 'index.ts', //要生成的文件名称
      output: path.resolve('./src/api'), // 生成的文件所在的文件夹,注意要使用 path.resolve 解析出绝对路径,否则路径可能会有错误
      input: path.resolve('./swagger.json'), // 从本地文件载入,路径问题同 output
      url: "http://xxx.com/springdoc/api-docs", // 如果从远程接口载入,只要返回的是json数据,不一定非要.json结尾
      httpClientType: 'axios', // or "fetch" 生成的接口类型
    })
  ]
})

配置完后,每次执行 vite 命令或每次保存都会重新生成,如果不想一直重新生成,可以在生成一次后注释掉配置。

生成的接口文件修改:

import axios, {
  AxiosInstance,
  AxiosRequestConfig,
  AxiosResponse,
  HeadersDefaults,
  ResponseType
} from 'axios'

修改成,不然会报错

import axios from 'axios'

import type {
  AxiosInstance,
  AxiosRequestConfig,
  AxiosResponse,
  HeadersDefaults,
  ResponseType
} from 'axios'

然后把 baseURL 那一行注释掉

constructor({
  securityWorker,
  secure,
  format,
  ...axiosConfig
}: ApiConfig<SecurityDataType> = {}) {
  this.instance = axios.create({
    ...axiosConfig,
    // baseURL: axiosConfig.baseURL || 'http://xxx/com'
  })
  this.secure = secure
  this.format = format
  this.securityWorker = securityWorker
}

页面中使用:

import { Api } from '@/api'
const { getUserList } = new Api().api

getUserList()

总结

两种方式都可以根据 openapi+swagger 生成的接口描述转换成前端可使用的接口方法,两种方式都需要对生成的接口文件进行修改,不同的是 @umijs/openapi 方式生成文件结构分层更清晰,而 swagger-typescript-api 则是把生成接口汇总到一个文件里,这样会使文件越来越大,而且需要先 new 一下才能使用,综合比较使用 @umijs/openapi 的方式可能更好,当然也要结合实际的项目需求来最终确定使用哪种方式。

PS:写作不易,如要转裁,请标明转载出处。
%{ comment.page.total }条评论

猜你想看

微信小程序:前端开发宝典

最近文章
工具操作
  • 内容截图
  • 全屏
登录
注册
回顶部