SwaggerをTypeScriptに変換してAPIリクエストで型チェックを有効にする


APIリクエストにもTSの型補完が欲しい

APIエンドポイントを文字列で指定するせいで型チェックや型補完が効かないというTypeScriptの課題を解決するために開発したのがaspida
※参考記事:Web APIに型を付与する"Aspida"が結構便利な話

一見便利ですが、エンドポイントの数だけ型定義ファイルを作る必要があります
なので大規模プロジェクトでaspidaを使おうとすると、膨大な数の型定義ファイルを手作業で作らねばならず導入はかなり辛い・・・
そこで、Swagger(とOpenAPI)をaspidaの型定義ファイルに一発変換するnpmモジュールを作ったので解説します


https://github.com/aspida/openapi2aspida

定番のPetStoreをTypeScriptに変換

Swaggerを知っているなら誰もが最初に見る「Swagger Petstore」を実際に変換して、レスポンスを取得してみます

設定ファイル

プロジェクトのディレクトリルートにaspida.config.jsという名前でaspidaの設定ファイルを作成し、swagger.jsonのURLを記述します
Swagger Petstoreのサイト上部にあるJSONのURLをコピペしました

                 ↓これ

型定義ファイル生成

$ mkdir sample
$ cd sample
$ npx openapi2aspida -i https://petstore.swagger.io/v2/swagger.json

sample/apiディレクトリにファイルが色々生成されます
ローカルのSwagger/OpenAPIファイルを変換したい場合は-iオプションにカレントディレクトリからの相対パスを渡してください
json/yaml両方の拡張子に対応してます

APIリクエスト

--save-dev付けるとか付けないとかあるけどとりあえずまとめてインストール

$ npm init -y
$ npm install @aspida/axios axios typescript ts-node @types/node

petを作成して取得するだけのコードです
エンドポイントを文字列ではなくプロパティとメソッドで組み立てるのでVSCodeの型補完や型チェックの恩恵を受けられます

index.ts
import axiosClient from '@aspida/axios'
import api from "./api/$api"
import { Pet } from './api/@types'

;(async () => {
  const client = api(axiosClient())
  const petId = 100
  const body: Pet = {
    id: petId,
    name: 'hoge',
    photoUrls: [],
    status: 'available'
  }

  await client.pet.$post({ body }) // petを新規作成
  const pet = await client.pet._petId(petId).$get() // 作成したpetを取得
  console.log(pet)
})()

作成したTSファイルを実行するnpmスクリプトを追加

package.json
{
  "scripts": {
    "start": "ts-node index.ts"
  }
}

実行

$ npm start
# { id: 100, name: 'hoge', photoUrls: [], tags: [], status: 'available' }

実際にswagger.ioのサーバーにリクエストが飛んで自分で作成したペットの情報をGETできました

まとめ

Swaggerファイルさえ出力できれば、LaravelやRailsのコードからTypeScriptの型定義を自動生成できるイメージが伝わったはずです
これはスゴイ!と感じたらGitHubにスター押してもらえると非常に嬉しいです
バグとか不足機能があれば日本語でいいのでQiitaのコメントかGitHubのIssueに投稿してください

aspida日本語ドキュメント:https://github.com/aspida/aspida/tree/master/packages/aspida/docs/ja