swagger-axios-codegen
一个使用了axios和typescript的swagger客户端
< v0.16 需要 node > v10.0.0
>= v0.16 需要 node >= v16
它将始终解析 axios.response.data
或者使用 Promise 拒绝 axios.error
支持其他类似 axios
的库,例如 Fly.js,需要设置ISwaggerOptions.useCustomerRequestInstance = true
ES6版本是通过调用TypeScript生成的
欢迎PR和提交问题
顺便说一句,你可以通过 Star 支持这个项目 ⭐️ ⭐️ ⭐️ ⭐️ ⭐️
示例
更新日志
贡献指南
快速开始
yarn add swagger-axios-codegen
export interface ISwaggerOptions {
serviceNameSuffix?: string
enumNamePrefix?: string
methodNameMode?: 'operationId' | 'path' | 'shortOperationId' | ((reqProps: IRequestMethod) => string)
classNameMode?: 'parentPath' | 'normal' | ((path: string, method: string, reqProps:IRequestMethod) => string)
/** 仅在 classNameMode='parentPath' 时生效 */
pathClassNameDefaultName?: string
outputDir?: string
fileName?: string
remoteUrl?: string
source?: any
useStaticMethod?: boolean | undefined
useCustomerRequestInstance?: boolean | undefined
include?: Array<string | IInclude>
/** 包含在过滤过程中未包含的类型 **/
includeTypes?: Array<string>
format?: (s: string) => string
/** 匹配 with tsconfig */
strictNullChecks?: boolean | undefined
/** definition Class mode */
modelMode?: 'class' | 'interface'
/** 使用 class-transformer 转换结果 */
useClassTransformer?: boolean
/** 强制指定 swagger 或 openAPI 版本 */
openApi?: string | undefined
/** 扩展文件 URL。它将插入服务方法前 */
extendDefinitionFile?: string | undefined
/** 标记泛型类型 */
extendGenericType?: string[] | undefined
/** 生成验证模型(仅限类模式) */
generateValidationModel?: boolean
/** 拆分请求服务。不能与 sharedServiceOptions 一起使用 */
multipleFileMode?: boolean | undefined
/** URL 前缀过滤器 */
urlFilters?: string[] | null | undefined
/** 共享服务选项到多个服务。不能与 MultipleFileMode 一起使用 */
sharedServiceOptions?: boolean | undefined
/** 是否使用头参数 */
useHeaderParameters?: boolean
}
const defaultOptions: ISwaggerOptions = {
serviceNameSuffix: 'Service',
enumNamePrefix: 'Enum',
methodNameMode: 'operationId',
classNameMode: 'normal',
pathClassNameDefaultName: 'Global',
outputDir: './service',
fileName: 'index.ts',
useStaticMethod: true,
useCustomerRequestInstance: false,
include: [],
strictNullChecks: true,
/** definition Class mode,自动使用 interface 模式简化代码 */
modelMode: 'interface',
useClassTransformer: false
}
使用本地 swagger api json
const { codegen } = require('swagger-axios-codegen')
codegen({
methodNameMode: 'operationId',
source: require('./swagger.json')
})
使用远程 swagger api json
const { codegen } = require('swagger-axios-codegen')
codegen({
methodNameMode: 'operationId',
remoteUrl:'你远程的 URL'
})
使用静态方法
codegen({
methodNameMode: 'operationId',
remoteUrl: 'http://localhost:22742/swagger/v1/swagger.json',
outputDir: '.',
useStaticMethod: true
});
前
import { UserService } from './service'
const userService = new UserService()
await userService.GetAll();
后
import { UserService } from './service'
await UserService.GetAll();
使用自定义 axios 实例
import axios from 'axios'
import { serviceOptions } from './service'
const instance = axios.create({
baseURL: 'https://some-domain.com/api/',
timeout: 1000,
headers: {'X-Custom-Header': 'foobar'}
});
serviceOptions.axios = instance
使用其他库
import YourLib from '<Your lib>'
import { serviceOptions } from './service'
serviceOptions.axios = YourLib
过滤服务和方法
通过 multimatch 使用 'include' 设置进行筛选
codegen({
methodNameMode: 'path',
source: require('../swagger.json'),
outputDir: './swagger/services',
include: [
'*',
// 'Products*',
'!Products',
{ 'User': ['*', '!history'] },
]
})
如果你的服务名称中使用了特殊字符(即第一个标签),你必须假设它们已经转义。
例如,服务名称为 MyApp.FirstModule.Products
, MyApp.FirstModule.Customers
, MyApp.SecondModule.Orders
:
// API
"paths": {
"/Products/Get": {
"post": {
"tags": [
"MyApp.FirstModule.Products"
],
"operationId": "Get",
// Codegen config
codegen({
methodNameMode: 'path',
source: require('../swagger.json'),
outputDir: './swagger/services',
include: ['MyAppFirstModule*'] // 只有Products和Customers会被包含。如你所见,点被解释为合同名称。
})
使用 class-transformer 转换结果
这对于想将日期转换为实际日期对象的用户很有帮助。Swagger 可以为不同类型定义字符串格式。其中两个格式是 date
和 date-time
如果 class-transformer
启用并且字符串上设置了格式,结果字符串将转换为 Date
实例。
// swagger.json
{
"ObjectWithDate": {
"type": "object",
"properties": {
"date": {
"type": "string",
"format": "date-time"
}
}
}
}
const { codegen } = require('swagger-axios-codegen')
codegen({
methodNameMode: 'operationId',
source:require('./swagger.json'),
useClassTransformer: true,
})
生成类:
export class ObjectWithDate {
@Expose()
@Type(() => Date)
public date: Date;
}
服务方法将转换json响应并返回该类的实例
使用验证模型
codegen({
...
modelMode: 'class',
generateValidationModel: true
});
上述选项结合类模型模式允许呈现模型验证规则。结果如下所示:
export class FooFormVm {
'name'?: string;
'description'?: string;
constructor(data: undefined | any = {}) {
this['name'] = data['name'];
this['description'] = data['description'];
}
public static validationModel = {
name: { required: true, maxLength: 50 },
description: { maxLength: 250 },
};
}
因此你可以在应用程序中使用验证模型:
function isRequired(vm: any, fieldName: string): boolean {
return (vm && vm[fieldName] && vm[fieldName].required === true);
}
function maxLength(vm: any, fieldName: string): number {
return (vm && vm[fieldName] && vm[fieldName].maxLength ? vm[fieldName].maxLength : 4000);
}
现在你可以使用这些函数
var required = isRequired(FooFormVm.validationModel, 'name');
var maxLength = maxLength(FooFormVm.validationModel, 'description');
目前只支持两个规则 - required
和 maxLength
。
一些解决方案
1.引用参数
参见 #53,使用包 json-schema-ref-parser
2.与 Microservice Gateway
一起使用
const {codegen} = require('swagger-axios-codegen')
const axios = require('axios')
// 主机地址
const host = 'http://your-host-name'
//
const modules = [
...
]
axios.get(`${host}/swagger-resources`).then(async ({data}) => {
console.warn('code', host)
for (let n of data) {
if (modules.includes(n.name)) {
try {
await codegen({
remoteUrl: `${host}${n.url}`,
methodNameMode: 'operationId',
modelMode: 'interface',
strictNullChecks: false,
outputDir: './services',
fileName: `${n.name}.ts`,
sharedServiceOptions: true,
extendDefinitionFile: './customerDefinition.ts',
})
} catch (e) {
console.log(`${n.name} 服务错误`, e.message)
}
}
}
})