Skip to content

Commit 49c7084

Browse files
committed
feat: add comprehensive documentation for genapi, including a new BLOG.md file detailing features and usage; update README with quick start instructions and schema mode details; enhance ESLint configuration to ignore generated test files
1 parent 7d6c2bc commit 49c7084

84 files changed

Lines changed: 7512 additions & 7 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

BLOG.md

Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
# 告别手写 API 调用!用 genapi 自动生成 TypeScript API
2+
3+
从前有一个 **genapi** 的工具,它能从 OpenAPI/Swagger,或者任意的数据源自动生成类型安全的 TS/JS API 代码。
4+
5+
今天他重构并且升级到了 4.0.0 版本,支持了很多新的功能,甚至有了文档、交互性浏览页面、测试也更加完善了。
6+
7+
## 手写 API 的痛
8+
9+
每次对接后端接口,我都要:
10+
1. 打开 Swagger 文档
11+
2. 复制接口路径和参数
12+
3. 手写请求函数
13+
4. 手动定义类型
14+
5. 接口变更后,再重复一遍
15+
16+
最麻烦就是后端改了接口但忘记通知前端,运行时才发现类型不匹配。这种重复劳动浪费时间,还容易出错。
17+
18+
genapi 可以直接读取 OpenAPI 文档,自动生成类型安全的 API 调用代码。接口变更后,重新运行一下命令就能同步更新。
19+
20+
## genapi 是什么?
21+
22+
是一个 API 代码生成器,能把 OpenAPI 2.0/3.x 规范转换成 TS/JS 的 API 调用代码。
23+
24+
它支持多种 HTTP 客户端:
25+
- `axios` - 最常用的 Promise 请求库
26+
- `fetch` - 浏览器原生 API
27+
- `ky` - 轻量优雅的请求库
28+
- `got` - Node.js 友好的请求库
29+
- `ofetch` - 更好的 fetch,带 TypeScript 支持
30+
- `uni` - uniapp 的网络请求库
31+
32+
每种客户端都支持生成 TypeScript 和 JavaScript 两种版本。
33+
34+
## 快速上手
35+
36+
```bash
37+
npx genapi init
38+
```
39+
40+
完成后会在项目根目录生成 `genapi.config.ts`,把 `input` 改成你的 API JSON 地址就行。
41+
42+
接着运行生成命令:
43+
44+
```bash
45+
npm run genapi
46+
```
47+
48+
## 配置文件(`genapi.config.ts`
49+
50+
```ts
51+
import { defineConfig } from '@genapi/core'
52+
import { axios } from '@genapi/presets'
53+
54+
export default defineConfig({
55+
preset: axios.ts,
56+
// 你的 Swagger API 文档地址
57+
input: 'http://example.com/api-docs',
58+
output: {
59+
main: 'src/api/index.ts',
60+
type: 'src/api/index.type.ts',
61+
},
62+
meta: {
63+
// API 基础 URL,会传递给 axios
64+
baseURL: 'import.meta.env.VITE_APP_BASE_API',
65+
// 自定义响应类型提取,默认是 'T'
66+
responseType: 'T extends { data?: infer V } ? V : void',
67+
},
68+
})
69+
```
70+
71+
生成后的代码大概是这样的:
72+
73+
```ts
74+
// src/api/index.ts
75+
import axios from 'axios'
76+
77+
export function getUsersId(id: string) {
78+
return axios.get<User>(`/users/${id}`)
79+
}
80+
81+
export function putUsersId(id: string, data: UpdateUserDto) {
82+
return axios.put<User>(`/users/${id}`, data)
83+
}
84+
```
85+
86+
类型定义会单独生成在 `src/api/index.type.ts`
87+
88+
## 几个实用功能
89+
90+
### 多服务支持
91+
92+
项目有多个后端服务的话,可以这样配置:
93+
94+
```ts
95+
export default defineConfig({
96+
meta: {
97+
baseURL: 'https://api.example.com',
98+
},
99+
servers: [
100+
{
101+
input: 'http://user-service/api-docs',
102+
output: { main: 'src/api/user.ts' }
103+
},
104+
{
105+
input: 'http://order-service/api-docs',
106+
output: { main: 'src/api/order.ts' }
107+
},
108+
]
109+
})
110+
```
111+
112+
所有服务会继承顶层配置,但可以单独指定输出路径。
113+
114+
### Schema 模式
115+
116+
`fetch``ofetch` 预设支持 Schema 模式,生成基于 schema 的类型安全 fetch API。
117+
118+
先安装 `fetchdts`
119+
120+
```bash
121+
npm i -D fetchdts
122+
```
123+
124+
配置:
125+
126+
```ts
127+
import { defineConfig } from '@genapi/core'
128+
import { fetch } from '@genapi/presets'
129+
130+
export default defineConfig({
131+
preset: fetch.schema,
132+
input: 'https://petstore.swagger.io/v2/swagger.json',
133+
output: {
134+
main: 'src/api/index.ts',
135+
},
136+
})
137+
```
138+
139+
生成后的 `$fetch` 函数会自动提示路径和参数(类型完整):
140+
141+
```ts
142+
import { $fetch } from './api'
143+
144+
// IDE 会提示路径和参数
145+
const users = await $fetch('/users')
146+
const user = await $fetch('/users/123')
147+
```
148+
149+
### 自定义生成结果
150+
151+
生成的函数名或类型不符合命名规范时,可以用 `transform` 批量修改,或者用 `patch` 精确修改。两者可以组合使用,`transform` 先执行,`patch` 后执行:
152+
153+
```ts
154+
export default defineConfig({
155+
preset: axios.ts,
156+
input: 'https://petstore.swagger.io/v2/swagger.json',
157+
transform: {
158+
// 批量给函数名加前缀
159+
operation: name => `api_${name}`,
160+
// 批量去掉 Dto 后缀
161+
definition: name => name.endsWith('Dto') ? name.slice(0, -3) : name
162+
},
163+
patch: {
164+
operations: {
165+
// 精确重命名函数(transform 执行后)
166+
api_getUserUsingGET: 'fetchUser',
167+
// 修改参数和返回类型
168+
api_postUpdateUserUsingPOST: {
169+
name: 'updateUserInfo',
170+
parameters: [{ name: 'id', type: 'string', required: true }],
171+
responseType: 'UserResponse'
172+
}
173+
},
174+
definitions: {
175+
// 精确重命名类型
176+
User: 'UserInfo',
177+
// 覆盖类型定义
178+
Session: {
179+
name: 'Session',
180+
type: '{ name: string, age: number }'
181+
}
182+
}
183+
}
184+
})
185+
```
186+
187+
### Mock 数据生成
188+
189+
开启 `mockjs` 后,会为每个 API 函数生成 mock 方法:
190+
191+
```ts
192+
export default defineConfig({
193+
preset: axios.ts,
194+
input: 'https://petstore.swagger.io/v2/swagger.json',
195+
mockjs: true,
196+
})
197+
```
198+
199+
使用:
200+
201+
```ts
202+
import { getUser } from './api'
203+
204+
// 返回符合类型定义的 mock 数据
205+
const mockUser = getUser.mock()
206+
```
207+
208+
> 需要注意以下,得安装 `better-mock`
209+
210+
## 自定义管道
211+
212+
genapi 的核心是管道系统,如果你有特殊需求,例如想自定义数据源之类的,那就可以自定义管道:
213+
214+
```ts
215+
import pipeline, { compiler, dest, generate, original } from '@genapi/pipeline'
216+
import { axios } from '@genapi/presets'
217+
218+
export default defineConfig({
219+
preset: pipeline(
220+
// 读取配置
221+
config => axios.ts.config(config),
222+
// 获取数据源
223+
configRead => original(configRead),
224+
// 解析为数据图
225+
configRead => axios.ts.parser(configRead),
226+
// 编译为 AST
227+
configRead => compiler(configRead),
228+
// 生成代码字符串
229+
configRead => generate(configRead),
230+
// 输出文件
231+
configRead => dest(configRead),
232+
),
233+
})
234+
```
235+
236+
每个管道步骤都可以替换或扩展,灵活性很高。
237+
238+
## 写在最后
239+
240+
genapi 解决了 API 代码生成的痛点,把前端开发者从重复劳动里解放出来。虽然不能完全替代手写代码,但对于标准化的 REST API,确实能提升开发效率。
241+
242+
项目地址:[https://github.com/hairyf/genapi](https://github.com/hairyf/genapi)
243+
244+
大伙们在项目里是怎么处理 API 调用的?

README.md

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ API generator that converts OpenAPI (v2~v3) and other input sources into TypeScr
2727
- `swag-got-ts` / `swag-got-js`
2828
- `swag-ofetch-ts` / `swag-ofetch-js`
2929
- `swag-uni-ts` / `swag-uni-js`
30+
- 📋 **Schema Mode** - Generate type-safe fetch APIs using schema-based typing (supports `fetch` and `ofetch` presets)
3031
- 🛠️ **Customizable** - Flexible pipeline system for customizing the generation process
3132

3233
## Installation
@@ -40,7 +41,34 @@ npm i @genapi/core @genapi/presets -D
4041
4142
## Usage
4243

43-
Create a configuration file in your project root:
44+
### Quick Start with `init` Command
45+
46+
The easiest way to get started is using the interactive `init` command:
47+
48+
```bash
49+
npx genapi init
50+
```
51+
52+
This command will:
53+
1. Guide you through selecting a preset (axios, fetch, ky, got, ofetch, uni)
54+
2. Let you choose the mode (TypeScript, JavaScript, or Schema - if supported)
55+
3. Generate a `genapi.config.ts` or `genapi.config.js` file
56+
4. Optionally install required dependencies automatically
57+
58+
Example interaction:
59+
60+
```bash
61+
🚀 genapi init
62+
? Select preset: › axios
63+
? Select mode: › TS
64+
? Overwrite? › No / Yes
65+
? Install now? › No / Yes
66+
✨ Success
67+
```
68+
69+
### Manual Configuration
70+
71+
Alternatively, you can create a configuration file manually in your project root:
4472

4573
- `genapi.config.ts`
4674
- `genapi.config.js`
@@ -125,6 +153,72 @@ Run `genapi` and get:
125153

126154
![swag-axios-js](public/swag-axios-js.png)
127155

156+
## Schema Mode - Type-Safe Fetch API
157+
158+
Schema mode generates a type-safe fetch API using schema-based typing. It's available for `fetch` and `ofetch` presets and requires the `fetchdts` package.
159+
160+
```ts
161+
import { defineConfig } from '@genapi/core'
162+
import { fetch } from '@genapi/presets'
163+
164+
export default defineConfig({
165+
preset: fetch.schema,
166+
input: 'https://petstore.swagger.io/v2/swagger.json',
167+
output: {
168+
main: 'src/api/index.ts',
169+
},
170+
})
171+
```
172+
173+
This generates a `$fetch` function with full type safety:
174+
175+
```ts
176+
import type { TypedFetchInput, TypedFetchRequestInit, TypedFetchResponseBody, TypedResponse } from 'fetchdts'
177+
178+
// API Schema
179+
interface APISchema {
180+
'/users': {
181+
[Endpoint]: {
182+
GET: {
183+
response: User[]
184+
}
185+
}
186+
}
187+
'/users/{id}': {
188+
[DynamicParam]: {
189+
[Endpoint]: {
190+
GET: {
191+
response: User
192+
}
193+
}
194+
}
195+
}
196+
}
197+
198+
async function $fetch<T extends TypedFetchInput<APISchema>>(
199+
input: T,
200+
init?: TypedFetchRequestInit<APISchema, T>
201+
): Promise<TypedResponse<TypedFetchResponseBody<APISchema, T>>> {
202+
return ofetch(input, init as any) as Promise<TypedResponse<TypedFetchResponseBody<APISchema, T>>>
203+
}
204+
```
205+
206+
Usage:
207+
208+
```ts
209+
import { $fetch } from './api'
210+
211+
// Fully type-safe API calls
212+
const users = await $fetch('/users')
213+
const user = await $fetch('/users/123')
214+
```
215+
216+
**Note**: Schema mode requires `fetchdts` as a dev dependency. Install it with:
217+
218+
```bash
219+
npm i -D fetchdts
220+
```
221+
128222
## Patch - Static Patches
129223

130224
Make exact-match modifications to operations and type definitions:

eslint.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export default antfu(
55
{
66
type: 'lib',
77
pnpm: true,
8-
ignores: ['packages/**/*.md', 'docs/**/*.md'],
8+
ignores: ['packages/**/*.md', 'docs/**/*.md', 'test/fixtures/generated/**'],
99
},
1010
{
1111
rules: {

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"lint": "eslint --cache .",
1313
"typecheck": "pnpm -r run typecheck",
1414
"test": "vitest",
15+
"test:run": "vitest --run",
1516
"test:coverage": "vitest run --coverage",
1617
"automd": "pnpm --filter '@genapi/*' exec automd",
1718
"release": "bumpp -r && pnpm -r publish --access public",

0 commit comments

Comments
 (0)