😽
openapi-fetchで型安全な API クライアントを作る
軽量でfetch準拠でOpenAPI由来の型推論・補完がそのまま効くopenapi-fetchを使ってみました
パッケージインストール
npm install openapi-fetch
npm install -D openapi-typescript
1) OpenAPIを公開(今回はHonoを使用)
/doc でスキーマを返す。
import { OpenAPIHono } from '@hono/zod-openapi'
export const app = new OpenAPIHono()
app.doc('/doc', {
openapi: '3.1.0',
info: {
title: 'My API',
version: '1.0.0',
},
})
2) 型生成(openapi-typescript)
package.jsonにスクリプトを追加:
{
"scripts": {
"generate:open-api": "mkdir -p public/openapi/v1 && curl -o public/openapi/v1/openapi.json ${API_URL:-http://localhost:3000}/doc",
"generate:types": "openapi-typescript public/openapi/v1/openapi.json -o src/types/api/v1/api.d.ts",
"generate": "npm run generate:open-api && npm run generate:types"
}
}
スキーマを更新したらnpm run generateを実行して型を再生成します。
3) クライアント(openapi-fetch)
import createClient from 'openapi-fetch'
import type { paths } from '@/types/api/v1/api'
const client = createClient<paths>({ baseUrl: '/api/v1' })
// GET リクエスト
export async function getMemos(limit = 20) {
const { data, error, response } = await client.GET('/memos', {
params: { query: { limit } },
})
if (error) throw Object.assign(new Error('API Error'), { detail: error, status: response.status })
return data
}
// POST リクエスト
export async function createMemo(body: { title: string; content: string }) {
const { data, error, response } = await client.POST('/memos', {
body,
})
if (error) throw Object.assign(new Error('API Error'), { detail: error, status: response.status })
return data
}
パスの自動補完
client.POST() でパスを入力すると、OpenAPI スキーマから生成された全エンドポイントが補完されます。

リクエストボディの型チェック
必須プロパティが不足している場合、エディタで即座にエラーが表示されます。

レスポンスの型推論
data の型も自動的に推論され、補完が効きます。

まとめ
openapi-fetchを使うことで、パス/クエリ/ボディ/レスポンスまで補完が効き、仕様変更も型エラーで即検知できる構成にできました。
参考リンク
ちょっと株式会社(chot-inc.com)のエンジニアブログです。 フロントエンドエンジニア募集中! カジュアル面接申し込みはこちらから chot-inc.com/recruit/iuj62owig
Discussion