大家写我的项目的时候联调对接后端,写相应的 API 函数的时候会不会感觉很麻烦,我是这么感觉的,如果应用的 Typescript ,确保和后端的类型保持一致,还要手写类型,接口申请和返回参数定义类型成了繁琐的一件事件。

如果后端有提供接口形容的数据源(swagger、yapi 或其余源)等等,咱们就能够利用 aippgen 主动的生成接口与类型。

/** * @summary uploads an image * @method post */export function postPetPetIdUploadImage(data: FormData, paths: OpenAPITypes.PostPetPetIdUploadImagePath, config?: AxiosRequestConfig) {  const url = `/pet/${paths?.petId}/uploadImage`  http.request<Response<OpenAPITypes.ApiResponse>>({ url, data, ...config })}/** * @summary Add a new pet to the store * @method post */export function postPet(data: OpenAPITypes.Pet, config?: AxiosRequestConfig) {  const url = '/pet'  http.request<Response<void>>({ url, data, ...config })}
export type Response<T> = T;export interface ApiResponse {  code?: number;  type?: string;  message?: string;}export interface Category {  id?: number;  name?: string;}export interface Pet {  id?: number;  category?: Category;  name: string;  photoUrls: string[];  tags?: Tag[];  /** @description pet status in the store */  status?: string;}

aippgen(API Pipeline Generator)是 API 生成工具,其中 Pipeline 是管道的意思,apipgen 通过不同的管道反对不同的源和输入格局,目前 apipgen 官网默认反对 swag-ts-axiosswag-js-axios 两种管道,反对自定义管道,不同管道间能够复用和重组。

要应用它之前,咱们先在本地我的项目文件夹中装置:

pnpm add apipgen -D# Or Yarnyarn add apipgen --dev

应用

应用 apipgen 要先编写配置文件,由配置文件决定输出/输入的内容,反对多个格局的配置文件 .ts|.js|.cjs|.json

import { defineConfig } from 'apipgen'export default defineConfig({  /**   * 应用的编译解决管道,反对 npm 包(增加前缀apipgen-)或本地门路   *   * 默认反对 swag-ts-axios|swag-js-axios   * @default 'swag-ts-axios'   */  pipeline: 'swag-ts-axios',  // 输出源(swagger url 或 swagger json)以及输入源  // 如果有多个源,能够应用 server 字段  input: 'https://petstore.swagger.io/v2/swagger.json',  output: {    main: 'src/api/index.ts',    type: 'src/api/index.type.ts',  },  // API baseUrl,此配置将传递给 axios  baseURL: 'import.meta.env.VITE_APP_BASE_API',  // 自定义 responseType,默认 T  responseType: 'T extends { data?: infer V } ? V : void',})

配置后,应用 apipgen 脚本生成代码:

# run apipgenpnpm apipgen

提供源(input)

input 目前反对两个输出源 url|json

export default defineConfig({  // 间接输出服务 url  input: 'http://...api-docs',  // 或者抉择其余源  input: { /* url|json */ }})

多服务(Server)

如果有多个服务,能够应用 server 设置多个服务。顶层的其余配置会被用作附加配置

export default defineConfig({  baseUrl: 'https://...',  // 所有 server 都继承下层配置  server: [    { uri: '...', import: '...', output: {/* ... */} },    { uri: '...', import: '...', output: {/* ... */} },    { uri: '...', import: '...', output: {/* ... */} },  ]})

导入(Import)

当然咱们我的项目中可能会想自定义 axios 拦截器,或应用 axios.create 的新实例,这个时候能够应用 import 字段自定义导入申请的门路。

不介意过渡封装 axios,这会毁坏 axios 本来的性能

咱们先在雷同目录下定义一个 http.instance.ts 用于配置 axios 申请

// 应用 axios.create 创立新的实例const request = axios.create({  baseURL: 'https://...'})// 应用拦截器request.interceptors.request.use(/* ... */)request.interceptors.response.use(/* ... */)

接着咱们配置 apipgen.config 文件,增加 import 字段。

export default defineConfig({  pipeline: 'swag-ts-axios',  input: {    uri: 'https://petstore.swagger.io/v2/swagger.json'  },  output: {    main: 'src/apis/index.ts'  },  import: {    // 将理论的 http 申请导入门路更改为 './http.instance'    http: './http.instance'  }})

接着运行 apipgen,咱们就能失去具备拦截器的 axios 实例:

import http from "./http.instance";import { AxiosRequestConfig } from "axios";import * as OpenAPITypes from "./index.type";import { Response } from "./index.type";/** * @summary uploads an image * @method post */export function postPetPetIdUploadImage(data: FormData, paths: OpenAPITypes.PostPetPetIdUploadImagePath, config?: AxiosRequestConfig) {  const url = `/pet/${paths?.petId}/uploadImage`;  http.request<Response<OpenAPITypes.ApiResponse>>({ url, data, ...config });}

Swagger 转 Javascript Axios

如果你的我的项目是 Javascript, 应用 apipgen 的 swag-js-axios 管道还能够生成具备 TS 类型提醒的 JS 文件

export default defineConfig({  pipeline: 'swag-js-axios',  input: {    uri: 'https://petstore.swagger.io/v2/swagger.json',  },})
export default defineConfig({  pipeline: 'swag-js-axios',  input: {    uri: 'https://petstore.swagger.io/v2/swagger.json',  },})
/** * @summary uploads an image * @method post * @param {FormData} data * @param {import("./index.type").PostPetPetIdUploadImagePath} paths * @param {import("axios").AxiosRequestConfig=} config * @return {import("./index.type").Response<import("./index.type").ApiResponse>} */export function postPetPetIdUploadImage(data, paths, config) {  const url = `/pet/${paths?.petId}/uploadImage`  http.request({ url, data, ...config })}

管道(Pipeline)

apipgen 由非凡的解决管道运作,从输出 config 到最终 dest 输入文件作为一个残缺管道。

apipgen 在定义配置时传入 pipeline 参数反对 npm 包(前缀 apipgen-) 和本地门路。

咱们能够依据咱们不同的需要(源、调用的 http 申请库)自定义不同的解决管道:

export default defineConfig({  pipeline: './custom-pipe',})

而管道中由 apipgen 提供的 pipeline 函数定义。

// custom-pipe.ts// 应用 apipgen 提供的 pipeline 创立 API 管道生成器import { pipeline } from 'apipgen'// 每个管道都裸露了对应办法,能够进行复用并重组import { dest, generate, original } from 'apipgen-swag-ts-axios'function myCustomPipe(config) {  const process = pipeline(    // 读取配置,转换为外部配置,并提供默认值    config => readConfig(config),    // 获取数据源    configRead => original(configRead),    // 解析数据源为数据图表(graphs)    configRead => parser(configRead),    // 编译数据,转换为形象语法树(AST)    configRead => compiler(configRead),    // 生成代码(code)    configRead => generate(configRead),    // 利用 outputs 输入文件    configRead => dest(configRead),  )  return process(config)}function readConfig(config) {  // ...}function parser(configRead) {  // ...}function compiler(configRead) {  // ...}

如果大家感兴趣,会思考出一期怎么自定义 aippgen 管道的具体文章。

  • Hairy's Blog
  • Github/TuiMao