Using swagger-typescript-api to Generate Request Code in Frontend Projects
swagger-typescript-api? The docs read like a draft, so you still have to figure it out yourself. Those fancy modular options—what do they do besides throw errors? Just generate a single file, wrap it in a client, and save yourself the hassle every time.
目录4 个章节
Introduction
This swagger-typescript-api tool is pretty decent—it can generate TypeScript request code from a Swagger document
It includes type annotations, but unfortunately the docs aren't very detailed. I'm recording how to use it here so I don't have to search every time I generate code
Official docs: https://acacode.github.io/swagger-typescript-api/
Commands
Basic usage
npx swagger-typescript-api generate -p http://localhost:5000/swagger/v1/swagger.json -o src/api -n index.ts
If you're using bun, replace npx with bunx
After testing, I found that using this most basic command and putting all endpoints in a single file actually works best. Other options like --modular for modularization often cause the generated code to throw errors.
Available CLI Options Overview
(Compiled from the official docs and Fig.io)
-v,--versionOutput the current tool version-p,--path <路径或 URL>Specify the location of the Swagger/OpenAPI document (local path or network URL)-o,--output <目录路径>Directory for generated files (default./)-n,--name <文件名>Specify the output TypeScript API filename (defaultApi.ts)-t,--templates <模板路径>Use custom EJS templates to render the generation logic-d,--default-as-successAlso treat"default"response status codes as success responses (some Swagger specs usedefault), defaultfalse-r,--responsesGenerate extra request response information, including typings for error types--union-enumsGenerate all enums as TypeScript union types (T1 | T2 | TN)--add-readonlyAdd thereadonlymodifier to generated properties--route-typesGenerate type definitions related to API routes (such as parameter types)--client/--no-clientWhether to generate the API client class (default--client); using--no-clientgenerates only the types/data layer--enum-names-as-valuesUsex-enumNamesvalues as enum values, not just keys (defaultfalse)--extract-request-params/--extract-request-body/--extract-response-body/--extract-response-errorExtract request parameters, request body, response body, or error responses into standalone data contract types--modularSplit http client, data contracts, routes, and other code into multiple files (modular)--jsGenerate JavaScript modules and corresponding.d.tsdeclaration files--module-name-index <索引>When generating modularly, decide which part of the path to use for index grouping--module-name-first-tagSplit modules based on the API's first Tag- Network settings:
--disableStrictSSL(disable strict SSL verification)--disableProxy(disable proxy) - HTTP client selection:
--axios: generate request code with axios as the underlying client Others default to using fetch or an abstraction --unwrap-response-dataAutomatically unwrap thedatafield in the response and return the inner data directly--disable-throw-on-errorDo not throw an exception whenresponse.ok !== true(HTTP errors) (defaultfalse)--single-http-clientSupport passing in a single HTTP client instance when generating the API class (defaultfalse)- Output control:
--silent: only output error messages, otherwise silent - Type generation configuration:
--default-response <Type>: default type when the response schema is empty--type-prefix <前缀>/--type-suffix <后缀>: custom prefix/suffix for data model names - Other options:
--clean-output: clean the output directory (note: this deletes old files)--api-class-name <类名>: specify the generated API class name--patch: fix some minor errors in the Swagger source definition--debug: output extra debug information--another-array-type: generate arrays inArray<Type>form instead ofType[](defaultfalse)--sort-types: sort fields and types (defaultfalse)--extract-enums: extract all enums from inline interfaces into standalone TSenums - Help command:
--help,-h: list all command help information
Usage Example in Next.js
Taking the StarBlog API as an example
The directory structure in the Next.js project looks like this:
where photo.ts and blog.ts are generated
lib
├─ api
│ └─ starblog
│ ├─ photo.ts
│ ├─ client.ts
│ └─ blog.ts
└─ source.ts
You need to create a client.ts to make it easier to use. The code:
import { Api as BlogApi } from './blog';
import { Api as PhotoApi } from './photo';
// 直接导出类型
export type { Post, Photo, FeaturedPost, PostListApiResponse, PostApiResponsePaged } from './blog';
export type { PhotoApiResponsePaged } from './photo';
/**
* 获取API基础URL
* @param baseUrl 可选的基础URL
* @returns 最终的API基础URL
*/
function getApiBaseUrl(baseUrl?: string): string {
// 在服务端环境中,优先使用服务端API URL
return typeof window === 'undefined'
? (process.env.API_BASE_URL || baseUrl || process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:5000')
: (baseUrl || process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:5000');
}
/**
* 创建博客API客户端
* @param baseUrl 可选的基础URL
* @returns 博客API实例
*/
export function createBlogApi(baseUrl?: string): BlogApi<unknown> {
return new BlogApi({
baseUrl: getApiBaseUrl(baseUrl),
customFetch: fetch,
});
}
/**
* 创建照片API客户端
* @param baseUrl 可选的基础URL
* @returns 照片API实例
*/
export function createPhotoApi(baseUrl?: string): PhotoApi<unknown> {
return new PhotoApi({
baseUrl: getApiBaseUrl(baseUrl),
customFetch: fetch,
});
}
// 为了向后兼容,保留原有的函数名
export const createStarBlogApiClient = createBlogApi;
Making requests in a page
import {createBlogApi, createPhotoApi, Post, Photo} from '@/lib/api/starblog/client';
/**
* 获取推荐博客文章
*/
async function getFeaturedPosts(): Promise<Post[]> {
try {
const blogApi = createBlogApi();
const response = await blogApi.api.blogFeaturedList();
if (response.data?.successful && response.data?.data) {
return response.data.data;
}
return [];
} catch (error) {
console.error('获取推荐文章失败:', error);
return [];
}
}
/**
* 获取摄影作品
*/
async function getPhotos(): Promise<Photo[]> {
try {
const photoApi = createPhotoApi();
console.log('正在获取摄影作品,API基础URL:', process.env.NEXT_PUBLIC_API_BASE_URL);
const response = await photoApi.api.photoList({page: 1, pageSize: 8});
console.log('摄影作品API响应:', response.data);
if (response.data?.successful && response.data?.data) {
console.log('获取到的摄影作品数量:', response.data.data.length);
response.data.data.forEach((photo, index) => {
console.log(`摄影作品 ${index + 1}:`, {
id: photo.id,
title: photo.title,
filePath: photo.filePath,
fullUrl: `${process.env.NEXT_PUBLIC_API_BASE_URL}/media/photography/${photo.filePath}`
});
});
return response.data.data;
}
console.warn('摄影作品API响应不成功或无数据');
return [];
} catch (error) {
console.error('获取摄影作品失败:', error);
return [];
}
}
export default async function HomePage() {
// 在服务端并行获取数据
const [posts, photos] = await Promise.all([
getPosts(),
getPhotos()
]);
return (
<div>
<BlogPosts
posts={posts}
baseUrl={process.env.NEXT_PUBLIC_API_BASE_URL || ''}
/>
<PhotoGallery
photos={photos}
baseUrl={process.env.NEXT_PUBLIC_API_BASE_URL || ''}
/>
</div>
)
}
Done.
_EOF_
Using swagger-typescript-api to Generate Request Code in Frontend Projects
- 本文作者:
- 程序设计实验室
- 版权声明:
- 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
相关文章
在HTML中引入React和JSX
Vue 可以非常方便地与 Pure HTML 结合,代替 jQuery 的功能,有一次遇到类似的场景时,我就想 React 能不能也以这种方式接入 HTML 网页,从而提高开发效率。 结果当然是可以的,只不过在 HTML 里直接 JSX 似乎会降低一些性能… 凑合用吧
2023-07-16 · Web前端 · 约 1 分钟
2025年底的 TailwindCSS 组件库简单横评
TailwindCSS组件库多到让人选择困难。shadcn/ui虽优雅但不够全,Origin UI倒是堆了500+组件——这年头连UI都要内卷?大而全还是小而精,选型前先想清楚自己要不要加班调样式。
2025-11-23 · Web前端 · 约 1 分钟
纯前端实现词云展示+附微博热搜词云Demo代码
前言 最近工作中做了几个数据可视化大屏项目,其中也有用到了词云展示,以前做词云都是用python库来生成图片显示的,这次用了纯前端的实现~~(Ctrl+V真好用)~~,同时顺手做个微博热搜的词云然后记录一下~ 依赖 echarts 4.x echarts-wordcloud 1.1.3 tips:echarts-wordcloud现在有2.0和1.x两个版本,2.0对应echarts 5.x版本
2021-12-18 · Web前端 · 约 1 分钟
魔改了一下bootstrap-treeview组件,发布个NPM包体验一下
前言 之前在这篇文章 基于.NetCore开发博客项目 StarBlog - (8) 分类层级结构展示 中说到,我为了让文章分类列表支持层级结构,用了一个树形组件,不过这个组件太老了,使用的Bootstrap版本居然是3.x的,但又找不到更好的,只能硬着头皮用。 但实际效果有很多我不满意的,人家作者直接放弃了,在GitHub上标记项目为Archive状态,没辙。 感谢开源,我直接fork一份代码来
2022-05-27 · Web前端 · 约 1 分钟
讨论
共 0 条加载评论中…