typed-api-spec
typed-api-specはTypeScriptを用いたAPI定義のためのライブラリです。
特徴
TypeScriptによるシンプルな宣言的API定義
TypeScriptを利用している環境からであれば、単にimportするだけでAPI定義を参照することができます
API定義の記述時は、TypeScriptの型によるサポートを受けることができます
フレームワーク非依存でポータブル
いかなるフレームワークも仮定しません。任意のUIフレームワーク、サーバフレームワーク、バリデーションライブラリを利用可能です
利用するフレームワークを変更したり混ぜたりする場合も、typed-api-specによるAPI定義を変更する必要はありません
いくつかのサーバフレームワークにはopt-inのユーティリティツールを提供する予定です。現在はExpress向けの実装が存在します
クライアント向けの型情報の提供
fetchに追加の型情報を付与することで、安全にリクエストとレスポンスのハンドリングを行うことができます
ゼロランタイム: 型情報のみを提供するため、バンドルサイズに全く影響を与えません
利用例
API定義の例
code: api-spec.ts
type PathMap = DefineApiEndpoints<{
"/users": {
get: {
responses: {
200: { body: { userNames: string[] } };
400: { body: { errorMessage: string } };
};
};
};
}>;
バリデーションライブラリを用いた定義も可能です。現在はzodをサポートしています。
code: api-spec-with-zod.ts
export const pathMap = {
"/users": {
get: {
responses: {
200: { body: z.object({ userNames: z.string().array() })},
400: { body: z.object({ errorMessage: z.string() })},
},
},
}
} satisfies ZodApiEndpoints
export type PathMap = ToApiEndpoints<typeof pathMap>;
クライアント側では、fetchに型定義を付与します
code: fetch.ts
const fetchT = fetch as FetchT<typeof origin, PathMap>;
const res = await fetchT(${origin}/users);
if (!res.ok) {
// !res.okなのでres.json()の型は、Status Codeが20X以外のものに絞り込まれる
// ここでは400のレスポンスである { errorMessage: string }
const e = await res.json()
console.log(error: ${e.errorMessage})
return
}
// res.json()の型は、Status Codeが20Xのものに絞り込まれる
// ここでは200のレスポンスである { userNames: string[] }
const data = await res.json()
console.log(userNames: ${data.userNames})
インストール
code: install.sh
npm install @mpppk/typed-api-spec