moyan-api
v1.3.4
Published
使用OpenApi 生成TypeScript的api调用skd
Downloads
1,361
Maintainers
Readme
moyan-api
基于 OpenAPI 3 (OAS3) 规范自动生成 TypeScript API 调用 SDK 的工具。
功能特点
- 根据 OpenAPI 3 JSON 自动生成 TypeScript 类型安全的 API 调用类
- 支持本地文件和远程 URL 获取 API 定义
- 自动生成接口类型定义和 Schema 类型
- 支持自定义 API 类名前缀和请求路径前缀
- 内置请求拦截器和响应处理器
- 支持事件监听和自定义错误处理
安装
npm i moyan-api -S快速开始
1. 项目配置
在项目的 package.json 中添加配置:
{
"moyan-api": {
"output": "src", // 生成文件的输出目录,默认:src
"apijson": "moyan.api.json", // OpenAPI 3.0 本地 JSON 文件路径,默认:moyan.api.json
"jsonurl": "https://...", // 远程 OpenAPI JSON 地址(二选一)
"apiprefix": "Api", // 生成的 SDK 类名前缀,默认:Api
"pathprefix": "/api", // 请求路径前缀,默认:空
"dirname": "api" // 生成的 SDK 目录名,默认:api
}
}2. 准备 OpenAPI 数据
确保项目根目录存在 OpenAPI 3.0 格式的 JSON 文件(如 moyan.api.json),或在 package.json 中配置 jsonurl 从远程获取。
3. 生成 SDK
在项目根目录运行命令:
npx moyan-api或使用 CLI 参数:
npx moyan-api -a moyan.api.json -o src -af Api -pp /api命令执行后,会在指定目录(默认 src/api)生成以下文件:
| 文件 | 说明 |
|------|------|
| index.ts | API 调用类定义 |
| schemas.ts | 数据类型定义 |
4. 配置请求类
在使用 API 之前,需要配置 ApiCall 的请求实现。建议在 src/lib/api/config.ts(路径可自定义)中创建配置:
import { ElMessage } from 'element-plus'
import { getConfig } from '../../config'
import axios, { AxiosInstance, AxiosRequestConfig } from 'axios'
import { ApiCall, ApiEntity } from 'moyan-api'
const AXIOS = Symbol('mo#Api#axios')
export class MoAxios {
static [AXIOS]: AxiosInstance
options: any = {}
constructor(options: any = {}) {
this.options = options
}
get $axios() {
if (!MoAxios[AXIOS]) {
MoAxios[AXIOS] = axios.create(this.config.axios)
this.init()
}
return MoAxios[AXIOS]
}
get config() {
return getConfig()
}
init() {
this.$axios.interceptors.response.use(
(res) => {
if (typeof this.options.render === 'function') {
return this.options.render(res)
}
return res
},
async (error) => {
if (error && error.response) {
switch (error.response.status) {
case 502:
error.message = '网关错误'
break
case 504:
error.message = '网关超时'
break
case 505:
error.message = '版本不受支持'
break
default:
error.message = error.response.data.message
break
}
}
throw error
}
)
}
request(apiEntity: ApiEntity) {
const url = `${apiEntity.path}`
const requestOptions: AxiosRequestConfig = {
responseType: 'json',
baseURL: this.config.moApi.baseURL,
url,
method: apiEntity.method,
headers: {}
}
if (apiEntity.method === 'GET') {
requestOptions.params = apiEntity.params
} else {
requestOptions.data = apiEntity.params
}
return this.$axios(requestOptions)
}
}
// 成功提示处理器
ApiCall.hintSuccessHandler = (apiCall) => {
ApiCall.hasPrompted = true
ElMessage.success({
message: apiCall.successMsg,
onClose: () => {
ApiCall.hasPrompted = false
}
})
}
// 失败提示处理器
ApiCall.hintFailHandler = (apiCall) => {
ApiCall.hasPrompted = true
apiCall.failMsg &&
ElMessage.error({
message: apiCall.failMsg,
onClose: () => {
ApiCall.hasPrompted = false
}
})
}
// 注册请求实现
ApiCall.use(new MoAxios())5. 调用 API
配置完成后,即可在项目中调用生成的 API:
// GET 请求 - 使用 params
new ApiGetUser({ params: { id: 1 } }).then((res) => {
// 处理响应
})
// GET 请求 - 使用 query(路径参数)
new ApiGetUser({ query: { id: 1 } }).then((res) => {
// 处理响应
})
// PUT 请求 - 带路径参数和请求体
new ApiUpdateUser({
query: { id: 1 },
params: { name: '张三' }
}).then((res) => {
// 处理响应
})CLI 参数
| 参数 | 简写 | 说明 |
|------|------|------|
| --apijson | -a | OpenAPI JSON 文件路径 |
| --output | -o | 输出目录路径 |
| --dirname | -d | 生成的 SDK 目录名 |
| --jsonurl | -j | 远程 OpenAPI 数据地址 |
| --apiprefix | -af | 生成的 SDK 类名前缀 |
| --pathprefix | -pp | 请求路径前缀 |
编程方式使用(多配置批量生成)
如果需要同时生成多个模块的 API SDK,可以创建配置文件使用编程方式调用:
// generate-api.js
const { ApisdkCreator } = require('moyan-api/dist/main.js')
const { Program } = require('moyan-api/dist/program.js')
const configs = [
{
jsonurl: 'http://localhost:8080/apiDoc/main-app',
output: './src/apis',
dirname: 'main-app'
},
{
jsonurl: 'http://localhost:8080/apiDoc/micro-system',
output: './src/apis',
dirname: 'micro-system'
},
]
const create = async () => {
for (let i = 0; i < configs.length; i++) {
await new ApisdkCreator(new Program(configs[i])).create()
}
}
create()在 package.json 中添加脚本:
{
"scripts": {
"generate-api": "node generate-api.js"
}
}然后运行:
npm run generate-apiProgram 配置项
| 属性 | 说明 |
|------|------|
| jsonurl | 远程 OpenAPI JSON 地址 |
| apijson | 本地 OpenAPI JSON 文件路径 |
| output | 输出目录路径 |
| dirname | 生成的 SDK 目录名 |
| apiprefix | 生成的 SDK 类名前缀 |
| pathprefix | 请求路径前缀 |
导出的类型和接口
import {
ApiCall, // API 调用基类
ApiEntity, // API 实体接口
ApiCallProps, // API 调用参数类型
SubApiEntity, // 子 API 实体接口
ObjectAny, // 任意对象类型
Option, // 请求选项类型
MoMethod // HTTP 方法类型
} from 'moyan-api'请求选项 (Option)
interface Option {
fileName?: string // 下载文件的文件名
prefix?: boolean // 是否使用 API 的 prefix,默认 true
hintSuccess?: boolean // 是否显示成功提示,默认 true
hintFail?: boolean // 是否显示失败提示,默认 true
showLoading?: boolean // 是否显示加载蒙版,默认 false
loading?: boolean // 加载状态
successMsg?: string | ((res: any) => string) // 成功提示消息
failMsg?: string | ((err: any) => string) // 失败提示消息
ext?: Record<string, any> // 扩展字段
}事件监听
ApiCall 内置了事件系统,可用于监听请求状态:
import { ApiEvents } from 'moyan-api'
// 监听请求成功
ApiCall.emitter.on(ApiEvents.HintSuccess, (apiCall) => {
console.log('请求成功提示已显示')
})
// 监听请求失败
ApiCall.emitter.on(ApiEvents.HintFail, (apiCall) => {
console.log('请求失败提示已显示')
})
// 监听 401 未授权
ApiCall.emitter.on(ApiEvents.Unauthorized, (apiCall) => {
// 处理登出逻辑
})生成的 API 类结构
每个 API 类继承自 ApiCall<ReqType, ResType>:
export class ApiGetUser extends ApiCall<GetUserReq, GetUserRes> {
path = '/api/user/{id}'
method: MoMethod = 'GET'
auth = true
}项目链接
- Gitee: https://gitee.com/ymoo/moyan-api
- npm: https://www.npmjs.com/package/moyan-api
