@@ -4,8 +4,170 @@ title: openapi-fetch
4
4
5
5
<img src =" /assets/openapi-fetch.svg " alt =" openapi-fetch " width =" 216 " height =" 40 " />
6
6
7
+ ` openapi-fetch ` 是一个类型安全的` fetch ` 客户端,用于拉取您的OpenAPI模式。大小为** 5 kb** ,几乎没有运行时。适用于React、Vue、Svelte或纯JS。
8
+
9
+ | 库 | 大小(最小) | “GET” 请求 |
10
+ | :------------------------- | -----------: | :-------------------------- |
11
+ | openapi-fetch | ` 5 kB ` | ` 278k ` 操作/秒(最快) |
12
+ | openapi-typescript-fetch | ` 4 kB ` | ` 130k ` 操作/秒(2.1× 较慢) |
13
+ | axios | ` 32 kB ` | ` 217k ` 操作/秒(1.3× 较慢) |
14
+ | superagent | ` 55 kB ` | ` 63k ` 操作/秒(4.4× 较慢) |
15
+ | openapi-typescript-codegen | ` 367 kB ` | ` 106k ` 操作/秒(2.6× 较慢) |
16
+
17
+ 语法灵感来自流行的库,如` react-query ` 或` Apollo client ` ,但没有所有这些功能,并且包大小仅为5 kb。
18
+
19
+ ``` ts
20
+ import createClient from " openapi-fetch" ;
21
+ import type { paths } from " ./api/v1" ; // 由openapi-typescript生成
22
+
23
+ const client = createClient <paths >({ baseUrl: " https://myapi.dev/v1/" });
24
+
25
+ const {
26
+ data, // 仅在2XX响应存在时出现
27
+ error, // 仅在4XX或5XX响应存在时出现
28
+ } = await client .GET (" /blogposts/{post_id}" , {
29
+ params: {
30
+ path: { post_id: " 123" },
31
+ },
32
+ });
33
+
34
+ await client .PUT (" /blogposts" , {
35
+ body: JSON .stringify ({
36
+ title: " My New Post" ,
37
+ }),
38
+ });
39
+ ```
40
+
41
+ ` data ` 和` error ` 经过类型检查,并将其类型暴露给VS Code(以及任何其他支持TypeScript的IDE)的智能感知。同样,请求` body ` 也将检查其字段,如果缺少任何必需的参数或存在类型不匹配,则会出错。
42
+
43
+ ` GET() ` 、` PUT() ` 、` POST() ` 等是对原生 [ fetch API] ( https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API ) 的轻量包装(您可以 [ 替换为任何调用] ( /openapi-fetch/zh/api#create-client ) )。
44
+
45
+ 请注意,没有泛型,也没有手动类型化。您的端点的请求和响应已自动推断。这对于端点的类型安全性是一个巨大的改进,因为** 每个手动断言都可能导致错误** !这消除了以下所有问题:
46
+
47
+ - ✅ URL 或参数中的拼写错误
48
+ - ✅ 所有参数、请求体和响应均经过类型检查,并且与您的模式完全匹配
49
+ - ✅ 无需手动输入API
50
+ - ✅ 消除隐藏错误的 ` any ` 类型
51
+ - ✅ 还消除了可能隐藏错误的 ` as ` 类型覆盖
52
+ - ✅ 所有这些都在一个 ** 5 kb** 的客户端包中 🎉
53
+
54
+ ## 安装
55
+
7
56
::: warning
8
57
9
- This article is a stub. Please help [ expand it] ( https://github.com/drwpow/openapi-typescript/tree/main/docs/zh/ ) !
58
+ 当前版本的
` openapi-fetch ` 需要
` [email protected] ` (最新版本)。即将发布的破坏性更新将支持
` [email protected] ` 。
59
+
60
+ :::
61
+
62
+ 安装此库以及 [ openapi-typescript] ( /introduction ) :
63
+
64
+ ``` bash
65
+ npm i openapi-fetch
66
+ npm i -D openapi-typescript typescript
67
+ ```
68
+
69
+ ::: tip 强烈推荐
70
+
71
+ 在 ` tsconfig.json ` 中启用 [ noUncheckedIndexedAccess] ( https://www.typescriptlang.org/tsconfig#noUncheckedIndexedAccess ) ([ 文档] ( /advanced#enable-nouncheckedindexaccess-in-your-tsconfigjson ) )
72
+
73
+ :::
74
+
75
+ 接下来,使用 ` openapi-typescript ` 从您的 OpenAPI 模式生成 TypeScript 类型:
76
+
77
+ ``` bash
78
+ npx openapi-typescript ./path/to/api/v1.yaml -o ./src/lib/api/v1.d.ts
79
+ ```
80
+
81
+ 最后,请确保在您的项目中 ** 运行类型检查** 。这可以通过在您的 [ npm 脚本] ( https://docs.npmjs.com/cli/v9/using-npm/scripts ) 中添加 ` tsc --noEmit ` 来完成,如下所示:
82
+
83
+ ``` json
84
+ {
85
+ "scripts" : {
86
+ "test:ts" : " tsc --noEmit"
87
+ }
88
+ }
89
+ ```
90
+
91
+ 并在您的 CI 中运行 ` npm run test:ts ` 以捕获类型错误。
92
+
93
+ ::: tip
94
+ 使用 ` tsc --noEmit ` 来检查类型错误,而不要依赖于您的 linter 或构建命令。没有什么比 TypeScript 编译器本身更能准确地检查类型。
95
+ :::
96
+
97
+
98
+ ## 基本用法
99
+
100
+ 使用 ` openapi-fetch ` 而不是传统的代码生成的最大优点是不需要文档。` openapi-fetch ` 鼓励使用现有的 OpenAPI 文档,而不是试图找出要导入的函数或该函数需要哪些参数:
101
+
102
+ ![ OpenAPI 模式示例] ( /assets/openapi-schema.png )
103
+
104
+ ``` ts
105
+ import createClient from " openapi-fetch" ;
106
+ import type { paths } from " ./api/v1" ;
107
+
108
+ const client = createClient <paths >({ baseUrl: " https://myapi.dev/v1/" });
109
+
110
+ const { data, error } = await client .GET (" /blogposts/{post_id}" , {
111
+ params: {
112
+ path: { post_id: " my-post"
113
+
114
+ },
115
+ query: { version: 2 },
116
+ },
117
+ });
118
+
119
+ const { data, error } = await client .PUT (" /blogposts" , {
120
+ body: JSON .stringify ({
121
+ title: " New Post" ,
122
+ body: " <p>New post body</p>" ,
123
+ publish_date: new Date (" 2023-03-01T12:00:00Z" ).getTime (),
124
+ }),
125
+ });
126
+ ```
127
+
128
+ 1 . HTTP 方法直接从 ` createClient() ` 中提取
129
+ 2 . 将所需的 ` path ` 传递给 ` GET() ` 、` PUT() ` 等
130
+ 3 . TypeScript 接管其余部分,并为任何缺失或无效的内容返回有帮助的错误
131
+
132
+ ### 路径名
133
+
134
+ ` GET() ` 、` PUT() ` 、` POST() ` 等的路径名** 必须与您的模式完全匹配** 。请注意,在示例中,URL 为 ` /blogposts/{post_id} ` 。此库将快速替换所有 ` path ` 参数(以便进行类型检查)。
135
+
136
+ ::: tip
137
+
138
+ ` openapi-fetch ` 从 URL 推断类型。请使用静态字符串值而不是动态运行时值,例如:
139
+
140
+ - ✅ ` "/blogposts/{post_id}" `
141
+ - ❌ ` [...pathParts].join("/") + "{post_id}" `
10
142
11
143
:::
144
+
145
+ 该库还自动支持** 标签** 和** 矩阵** 序列化样式([ 文档] ( https://swagger.io/docs/specification/serialization/#path ) )。
146
+
147
+ ### 请求
148
+
149
+ ` GET() ` 请求所示需要 ` params ` 对象,该对象按类型(` path ` 或 ` query ` )分组 [ 参数] ( https://spec.openapis.org/oas/latest.html#parameter-object ) 。如果缺少必需的参数或参数类型不正确,将引发类型错误。
150
+
151
+ ` POST() ` 请求需要一个 ` body ` 对象,该对象提供了所有必需的 [ requestBody] ( https://spec.openapis.org/oas/latest.html#request-body-object ) 数据。
152
+
153
+ ### 响应
154
+
155
+ 所有方法都返回一个包含 ** data** 、** error** 和 ** response** 的对象。
156
+
157
+ ``` ts
158
+ const { data, error, response } = await client .GET (" /url" );
159
+ ```
160
+
161
+ | 对象 | 响应 |
162
+ | :--------- | :----------------------------------------------------------- |
163
+ | ` data ` | 如果 OK 则为 ` 2xx ` 响应;否则为 ` undefined ` |
164
+ | ` error ` | 如果不是 OK,则为 ` 5xx ` 、` 4xx ` 或 ` default ` 响应;否则为 ` undefined ` |
165
+ | ` response ` | [ 原始响应] ( https://developer.mozilla.org/en-US/docs/Web/API/Response ) 包含 ` status ` 、` headers ` 等 |
166
+
167
+ ## 支持
168
+
169
+ | 平台 | 支持 |
170
+ | :------------- | :----------------------------------------------------------- |
171
+ | ** 浏览器** | [ 查看 fetch API 支持] ( https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API#browser_compatibility ) (在所有主流浏览器中广泛可用) |
172
+ | ** Node** | >= 18.0.0 |
173
+ | ** TypeScript** | >= 4.7(建议使用 >= 5.0) |
0 commit comments