找回密码
 立即注册
首页 业界区 业界 使用 swagger-typescript-api 在前端项目里生成请求代码 ...

使用 swagger-typescript-api 在前端项目里生成请求代码

电棘缣 2025-11-27 03:05:02
前言

这个 swagger-typescript-api 工具还不错,可以根据 swagger 文档生成 TypeScript 请求代码
包含有类型注解,可惜文档不太详细,这里我记录一下使用方法,免得每次生成代码都要去搜索
官方文档: https://acacode.github.io/swagger-typescript-api/
命令

基础用法
  1. npx swagger-typescript-api generate -p http://localhost:5000/swagger/v1/swagger.json -o src/api -n index.ts
复制代码
如果是用 bun,则把 npx 替换为 bunx
我测试之后发现使用最基础的这个命令,把全部接口都放在一个文件反而最好,其他的比如 --modular 模块化参数,经常会导致生成的代码报错。
可用命令行参数一览

(整理自官方文档和 Fig.io)

  • -v, --version
    输出当前工具版本
  • -p, --path
    指定 Swagger/OpenAPI 文档的位置(本地路径或网络 URL)
  • -o, --output
    输出生成文件的目录(默认 ./)
  • -n, --name
    指定输出 TypeScript API 文件名(默认 Api.ts)
  • -t, --templates
    使用自定义 EJS 模板渲染生成逻辑
  • -d, --default-as-success
    将 "default" 响应状态码也视为成功响应(一些 Swagger 用 default),默认 false
  • -r, --responses
    生成额外的请求响应信息,包括出错类型的 typings
  • --union-enums
    将所有枚举生成成 TypeScript 联合类型(T1 | T2 | TN)
  • --add-readonly
    为生成的属性添加 readonly 修饰
  • --route-types
    生成 API 路由相关的类型定义(如参数类型等)
  • --client / --no-client
    是否生成 API 调用类(默认 --client),执行 --no-client 则只生成类型/数据层
  • --enum-names-as-values
    使用 x-enumNames 的值作为 enum 值,而不仅是 key(默认 false)
  • --extract-request-params / --extract-request-body / --extract-response-body / --extract-response-error
    将请求参数、请求体、响应体或错误响应提取成独立的数据契约类型
  • --modular
    将 http client、数据契约、路由等代码拆分成多个文件(模块化)
  • --js
    生成 JavaScript 模块和对应的 .d.ts 声明文件
  • --module-name-index
    在模块化生成时决定从路径的哪个部分做索引分组
  • --module-name-first-tag
    根据 API 的第一个 Tag 划分模块
  • 网络设置
    --disableStrictSSL(禁用严格 SSL 验证)
    --disableProxy(禁用代理)
  • HTTP 客户端选择
    --axios:生成以 axios 为底层客户端的请求代码
    其他默认使用 fetch 或抽象
  • --unwrap-response-data
    自动拆解响应中的 data 字段,直接返回内部数据
  • --disable-throw-on-error
    遇到 response.ok !== true(HTTP 错误)时不抛异常(默认 false)
  • --single-http-client
    生成 API 类时支持传入单一的 HTTP client 实例(默认 false)
  • 输出控制
    --silent:只输出错误信息,其它静默
  • 类型生成配置
    --default-response :响应 schema 为空时的默认类型
    --type-prefix  / --type-suffix :自定义数据模型名称前后缀
  • 其他选项
    --clean-output:清理输出目录(注意会删除旧文件)
    --api-class-name :指定生成的 API 类名称
    --patch:修正 Swagger 源定义中的一些小错误
    --debug:输出额外调试信息
    --another-array-type:生成 Array 形式数组而非 Type[](默认 false)
    --sort-types:对字段和类型排序(默认 false)
    --extract-enums:将所有枚举从 inline interface 中提取为独立的 TS enum
  • 帮助命令
    --help, -h:列出所有命令帮助信息
在 Next.js 里使用例子

以生成 StarBlog 的 API 接口为例
在 Next.js 项目中的目录结构是这样的:
其中 photo.ts  和 blog.ts 是生成的
  1. lib
  2. ├─ api
  3. │  └─ starblog
  4. │     ├─ photo.ts
  5. │     ├─ client.ts
  6. │     └─ blog.ts
  7. └─ source.ts
复制代码
这里需要创建一个 client.ts 方便使用,代码
  1. import { Api as BlogApi } from './blog';
  2. import { Api as PhotoApi } from './photo';
  3. // 直接导出类型
  4. export type { Post, Photo, FeaturedPost, PostListApiResponse, PostApiResponsePaged } from './blog';
  5. export type { PhotoApiResponsePaged } from './photo';
  6. /**
  7. * 获取API基础URL
  8. * @param baseUrl 可选的基础URL
  9. * @returns 最终的API基础URL
  10. */
  11. function getApiBaseUrl(baseUrl?: string): string {
  12.   // 在服务端环境中,优先使用服务端API URL
  13.   return typeof window === 'undefined'
  14.     ? (process.env.API_BASE_URL || baseUrl || process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:5000')
  15.     : (baseUrl || process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:5000');
  16. }
  17. /**
  18. * 创建博客API客户端
  19. * @param baseUrl 可选的基础URL
  20. * @returns 博客API实例
  21. */
  22. export function createBlogApi(baseUrl?: string): BlogApi<unknown> {
  23.   return new BlogApi({
  24.     baseUrl: getApiBaseUrl(baseUrl),
  25.     customFetch: fetch,
  26.   });
  27. }
  28. /**
  29. * 创建照片API客户端
  30. * @param baseUrl 可选的基础URL
  31. * @returns 照片API实例
  32. */
  33. export function createPhotoApi(baseUrl?: string): PhotoApi<unknown> {
  34.   return new PhotoApi({
  35.     baseUrl: getApiBaseUrl(baseUrl),
  36.     customFetch: fetch,
  37.   });
  38. }
  39. // 为了向后兼容,保留原有的函数名
  40. export const createStarBlogApiClient = createBlogApi;
复制代码
在页面里请求
  1. import {createBlogApi, createPhotoApi, Post, Photo} from '@/lib/api/starblog/client';
  2. /**
  3. * 获取推荐博客文章
  4. */
  5. async function getFeaturedPosts(): Promise<Post[]> {
  6.     try {
  7.         const blogApi = createBlogApi();
  8.         const response = await blogApi.api.blogFeaturedList();
  9.         if (response.data?.successful && response.data?.data) {
  10.             return response.data.data;
  11.         }
  12.         return [];
  13.     } catch (error) {
  14.         console.error('获取推荐文章失败:', error);
  15.         return [];
  16.     }
  17. }
  18. /**
  19. * 获取摄影作品
  20. */
  21. async function getPhotos(): Promise<Photo[]> {
  22.     try {
  23.         const photoApi = createPhotoApi();
  24.         console.log('正在获取摄影作品,API基础URL:', process.env.NEXT_PUBLIC_API_BASE_URL);
  25.         const response = await photoApi.api.photoList({page: 1, pageSize: 8});
  26.         console.log('摄影作品API响应:', response.data);
  27.         if (response.data?.successful && response.data?.data) {
  28.             console.log('获取到的摄影作品数量:', response.data.data.length);
  29.             response.data.data.forEach((photo, index) => {
  30.                 console.log(`摄影作品 ${index + 1}:`, {
  31.                     id: photo.id,
  32.                     title: photo.title,
  33.                     filePath: photo.filePath,
  34.                     fullUrl: `${process.env.NEXT_PUBLIC_API_BASE_URL}/media/photography/${photo.filePath}`
  35.                 });
  36.             });
  37.             return response.data.data;
  38.         }
  39.         console.warn('摄影作品API响应不成功或无数据');
  40.         return [];
  41.     } catch (error) {
  42.         console.error('获取摄影作品失败:', error);
  43.         return [];
  44.     }
  45. }
  46. export default async function HomePage() {
  47.     // 在服务端并行获取数据
  48.     const [posts, photos] = await Promise.all([
  49.         getPosts(),
  50.         getPhotos()
  51.     ]);
  52.     return (
  53.         
  54.             <BlogPosts
  55.                 posts={posts}
  56.                 baseUrl={process.env.NEXT_PUBLIC_API_BASE_URL || ''}
  57.                 />
  58.             <PhotoGallery
  59.                 photos={photos}
  60.                 baseUrl={process.env.NEXT_PUBLIC_API_BASE_URL || ''}
  61.                 />
  62.         
  63.     )
  64. }
复制代码
搞定

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册