Skip to content
@ternaus/openapi-fetch

TypeScript 向けの型安全な Fetch クライアント ​

@ternaus/openapi-fetch は、OpenAPI の型定義からリクエストとレスポンスの型を推論する Fetch クライアントです。

ts
import createClient from "@ternaus/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: {
    title: "新しい投稿",
  },
});

data と error は型チェックが行われ、VS Code や他の TypeScript 対応 IDE で Intellisense による補完が利用可能です。同様に、リクエストの body もフィールドが型チェックされ、必要なパラメータが不足している場合や型の不一致がある場合にはエラーが発生します。

GET(), PUT(), POST() などは、ネイティブの fetch API の薄いラッパーとして動作します(任意の呼び出しに変更することも可能です)。

ここで重要なのは、ジェネリクスや手動の型指定が一切不要で、エンドポイントのリクエストとレスポンスが自動的に推論されることです。これは、エンドポイントの型安全性を大幅に向上させます。なぜなら、手動でのアサーションはバグの原因となり得るからです!これにより、次のような問題がすべて解消されます:

  • ✅ URLやパラメータのタイプミスが起こらない
  • ✅ すべてのパラメータ、リクエストボディ、レスポンスが型チェックされ、スキーマと100%一致する
  • ✅ APIの手動での型指定が不要
  • ✅ バグを隠す可能性がある any 型の排除
  • ✅ バグを隠す可能性がある as による型の上書きも排除

セットアップ ​

このライブラリと openapi-typescript をインストールします:

bash
npm i @ternaus/openapi-fetch
npm i -D @ternaus/openapi-typescript typescript

tip 強く推奨

tsconfig.jsonで noUncheckedIndexedAccess を有効にしてください (ドキュメント)

次に、openapi-typescriptを使用してOpenAPIスキーマからTypeScriptの型を生成します:

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

最後に、プロジェクトで 型チェックを実行 してください。これは、tsc --noEmit を npm scripts に追加することで可能です:

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

そして、CIで npm run test:ts を実行して型エラーを検出します。

tip

tsc --noEmit を使用して型エラーをチェックし、リンターやビルドコマンドに依存しないようにしてください。TypeScriptコンパイラ自体ほど正確に型チェックを行えるものはありません。

基本的な使用方法 ​

@ternaus/openapi-fetch は、OpenAPI の型定義からリクエストとレスポンスの型を推論する Fetch クライアントです。

OpenAPI schema example

ts
import createClient from "@ternaus/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: {
    title: "New Post",
    body: "<p>New post body</p>",
    publish_date: new Date("2023-03-01T12:00:00Z").getTime(),
  },
});
  1. HTTPメソッドを createClient() から直接取得します。
  2. GET() , PUT() などに希望する path を渡します。
  3. TypeScriptが欠落しているものや無効なものがあれば有用なエラーを返します。

Pathname ​

GET() , PUT() , POST() などのpathnameは、スキーマと厳密に一致している必要があります。例では、URLは /blogposts/{post_id} です。このライブラリは、すべての path パラメータをすぐに置き換え、それらが型チェックされるようにします。

tip

openapi-fetch は URL から型を推論します。動的な実行時の値よりも静的な文字列値を優先してください。例:

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

このライブラリはまた、label および matrix のシリアライゼーションスタイルもサポートしています(ドキュメント)。

Request ​

GET() リクエストには、タイプごとにパラメータをグループ化する params オブジェクトが必要です( pathまたは query )。必須のパラメータが欠けている場合や、型が間違っている場合には、型エラーが発生します。

POST() リクエストでは、必要な requestBody データを提供する body オブジェクトが必要でした。

Response ​

すべてのメソッドはdata、errorおよび responseを持つオブジェクトを返します。

ts
const { data, error, response } = await client.GET("/url");
ObjectResponse
dataOKの場合 2xx レスポンス、そうでない場合 undefined
errorOKでない場合 5xx 、4xx 、または default レスポンス、それ以外は undefined
responseオリジナルのレスポンスであり、status, headers などを含みます。

Path-property スタイル ​

パスをプロパティとして選択する方が好ましい場合は、パスベースのクライアントを作成できます:

ts
import { createPathBasedClient } from "@ternaus/openapi-fetch";
import type { paths } from "./my-openapi-3-schema"; // openapi-typescriptで生成された型

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

client["/blogposts/{post_id}"].GET({
  params: { post_id: "my-post" },
  query: { version: 2 },
});

これにはパフォーマンスの影響があり、ミドルウェアを直接付与することはできません。 詳細については、wrapAsPathBasedClient を参照してください。

サポート ​

プラットフォームサポート
ブラウザfetch API サポートを参照 (主要なブラウザで広く利用可能)
Node24.15+ or 26
TypeScript>= 7.0

MIT licensed. Original package license notices remain with each package.