返回文章列表文章索引阅读全文
STARBLOG / 阅读手记
Web前端

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.

曦远 (DealiAxy)约 20 分钟
目录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, --version Output 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 (default Api.ts)
  • -t, --templates <模板路径> Use custom EJS templates to render the generation logic
  • -d, --default-as-success Also treat "default" response status codes as success responses (some Swagger specs use default), default false
  • -r, --responses Generate extra request response information, including typings for error types
  • --union-enums Generate all enums as TypeScript union types (T1 | T2 | TN)
  • --add-readonly Add the readonly modifier to generated properties
  • --route-types Generate type definitions related to API routes (such as parameter types)
  • --client / --no-client Whether to generate the API client class (default --client); using --no-client generates only the types/data layer
  • --enum-names-as-values Use x-enumNames values as enum values, not just keys (default false)
  • --extract-request-params / --extract-request-body / --extract-response-body / --extract-response-error Extract request parameters, request body, response body, or error responses into standalone data contract types
  • --modular Split http client, data contracts, routes, and other code into multiple files (modular)
  • --js Generate JavaScript modules and corresponding .d.ts declaration files
  • --module-name-index <索引> When generating modularly, decide which part of the path to use for index grouping
  • --module-name-first-tag Split 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-data Automatically unwrap the data field in the response and return the inner data directly
  • --disable-throw-on-error Do not throw an exception when response.ok !== true (HTTP errors) (default false)
  • --single-http-client Support passing in a single HTTP client instance when generating the API class (default false)
  • 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 in Array<Type> form instead of Type[] (default false) --sort-types: sort fields and types (default false) --extract-enums: extract all enums from inline interfaces into standalone TS enums
  • 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 许可协议。转载请注明出处!

相关文章

纯前端实现词云展示+附微博热搜词云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 条

良言一句三冬暖,恶语伤人六月寒。

加载评论中…