Skip to content
openapi-fetch

openapi-fetch是一个类型安全的fetch客户端,用于拉取您的OpenAPI模式。大小为5 kb,几乎没有运行时。适用于React、Vue、Svelte或纯JS。

大小(最小)“GET” 请求
openapi-fetch5 kB278k 操作/秒(最快)
openapi-typescript-fetch4 kB130k 操作/秒(2.1× 较慢)
axios32 kB217k 操作/秒(1.3× 较慢)
superagent55 kB63k 操作/秒(4.4× 较慢)
openapi-typescript-codegen367 kB106k 操作/秒(2.6× 较慢)

语法灵感来自流行的库,如react-queryApollo client,但没有所有这些功能,并且包大小仅为5 kb。

ts
import createClient from "openapi-fetch";
import type { paths } from "./my-openapi-3-schema"; // 由openapi-typescript生成

const client = createClient<paths>({ baseUrl: "https://myapi.dev/v1/" });

const {
  data, // 仅在2XX响应存在时出现
  error, // 仅在4XX或5XX响应存在时出现
} = await client.GET("/blogposts/{post_id}", {
  params: {
    path: { post_id: "123" },
  },
});

await client.PUT("/blogposts", {
  body: JSON.stringify({
    title: "My New Post",
  }),
});

dataerror经过类型检查,并将其类型暴露给VS Code(以及任何其他支持TypeScript的IDE)的智能感知。同样,请求body也将检查其字段,如果缺少任何必需的参数或存在类型不匹配,则会出错。

GET()PUT()POST()等是对原生 fetch API 的轻量包装(您可以 替换为任何调用)。

请注意,没有泛型,也没有手动类型化。您的端点的请求和响应已自动推断。这对于端点的类型安全性是一个巨大的改进,因为每个手动断言都可能导致错误!这消除了以下所有问题:

  • ✅ URL 或参数中的拼写错误
  • ✅ 所有参数、请求体和响应均经过类型检查,并且与您的模式完全匹配
  • ✅ 无需手动输入API
  • ✅ 消除隐藏错误的 any 类型
  • ✅ 还消除了可能隐藏错误的 as 类型覆盖
  • ✅ 所有这些都在一个 5 kb 的客户端包中 🎉

安装

WARNING

当前版本的 openapi-fetch 需要 [email protected](最新版本)。即将发布的破坏性更新将支持 [email protected]

安装此库以及 openapi-typescript

bash
npm i openapi-fetch
npm i -D openapi-typescript typescript

强烈推荐

tsconfig.json 中启用 noUncheckedIndexedAccess文档

接下来,使用 openapi-typescript 从您的 OpenAPI 模式生成 TypeScript 类型:

bash
npx openapi-typescript ./path/to/api/v1.yaml -o ./src/lib/api/v1.d.ts

最后,请确保在您的项目中 运行类型检查。这可以通过在您的 npm 脚本 中添加 tsc --noEmit 来完成,如下所示:

json
{
  "scripts": {
    "test:ts": "tsc --noEmit"
  }
}

并在您的 CI 中运行 npm run test:ts 以捕获类型错误。

TIP

使用 tsc --noEmit 来检查类型错误,而不要依赖于您的 linter 或构建命令。没有什么比 TypeScript 编译器本身更能准确地检查类型。

基本用法

使用 openapi-fetch 而不是传统的代码生成的最大优点是不需要文档。openapi-fetch 鼓励使用现有的 OpenAPI 文档,而不是试图找出要导入的函数或该函数需要哪些参数:

OpenAPI 模式示例

ts
import createClient from "openapi-fetch";
import type { paths } from "./my-openapi-3-schema"; // 由openapi-typescript生成

const client = createClient<paths>({ baseUrl: "https://myapi.dev/v1/" });

const { data, error } = await client.GET("/blogposts/{post_id}", {
  params: {
    path: { post_id: "my-post" },
    query: { version: 2 },
  },
});

const { data, error } = await client.PUT("/blogposts", {
  body: JSON.stringify({
    title: "New Post",
    body: "<p>New post body</p>",
    publish_date: new Date("2023-03-01T12:00:00Z").getTime(),
  }),
});
  1. HTTP 方法直接从 createClient() 中提取
  2. 将所需的 path 传递给 GET()PUT()
  3. TypeScript 接管其余部分,并为任何缺失或无效的内容返回有帮助的错误

路径名

GET()PUT()POST() 等的路径名必须与您的模式完全匹配。请注意,在示例中,URL 为 /blogposts/{post_id}。此库将快速替换所有 path 参数(以便进行类型检查)。

TIP

openapi-fetch 从 URL 推断类型。请使用静态字符串值而不是动态运行时值,例如:

  • "/blogposts/{post_id}"
  • [...pathParts].join("/") + "{post_id}"

该库还自动支持标签矩阵序列化样式(文档)。

请求

GET() 请求所示需要 params 对象,该对象按类型(pathquery)分组 参数。如果缺少必需的参数或参数类型不正确,将引发类型错误。

POST() 请求需要一个 body 对象,该对象提供了所有必需的 requestBody 数据。

响应

所有方法都返回一个包含 dataerrorresponse 的对象。

ts
const { data, error, response } = await client.GET("/url");
对象响应
data如果 OK 则为 2xx 响应;否则为 undefined
error如果不是 OK,则为 5xx4xxdefault 响应;否则为 undefined
response原始响应 包含 statusheaders

支持

平台支持
浏览器查看 fetch API 支持(在所有主流浏览器中广泛可用)
Node>= 18.0.0
TypeScript>= 4.7(建议使用 >= 5.0)

基于 MIT 许可发布