コンテンツにスキップ

OpenAPI 仕様書からのクライアントコード生成⚓︎

サーバー側で公開される Web API は、 OpenAPI 仕様書を自動生成しています(詳細は ASP.NET Core Web API プロジェクトの構成 を参照)。 Vue.js アプリケーションでは、 OpenAPI Generator を使用して、この OpenAPI 仕様書からクライアントコードを生成します。

事前準備⚓︎

OpenAPI 仕様書の出力設定 に示す手順に従って生成した OpenAPI 仕様書をローカルに保存します。ここでは、ファイル名を「dressca-api.json」とします。

JDK のインストール⚓︎

OpenAPI Generator を使用するためには、 Java 11 以降のランタイムと、システム環境変数 JAVA_HOME の設定が必要です。 Oracle JDK や Eclipse Temurin など、適当な JDK をインストールし、 JAVA_HOME を設定してください。

Axios⚓︎

Axios のインストール⚓︎

1
npm install axios

OpenAPI Generator⚓︎

OpenAPI Generator のインストール⚓︎

OpenAPI Generator をインストールします。ターミナルで以下のコマンドを入力します。

1
npm install -D @openapitools/openapi-generator-cli

OpenAPI Generator の設定⚓︎

package.json の scripts セクションにタスクを追加します。

タスクを登録する際の注意点

package.jsonにタスクを登録する際には、実行環境の OS に依存するコマンドの使用を避けるように注意する必要があります。 例えば、フォルダーを削除したい場合にrmdirコマンドを使用すると Windows 環境に依存してしまい、rmコマンドを使用すると UNIX 環境に依存してしまいます。 ここで開発環境が Windows であり、 CI 環境が UNIX の場合には、開発環境では実行できていたコマンドが CI 環境では実行できないといった問題が発生します。 そのため、 タスク中で OS コマンドを使用したい場合には、可能であれば Node.jsのAPI で代替するほうがベターです。

package.json
1
2
3
4
5
6
7
{
  "scripts": {
    "generate-client": "run-s openapi-client:clean openapi-client:generate --print-label",
    "openapi-client:clean": "node -e \"fs.promises.rm('./src/generated/api-client', {recursive: true, force: true})\"",
    "openapi-client:generate": "openapi-generator-cli generate -g typescript-axios -i ./../../dressca-backend/src/Dressca.Web/dressca-api.json --additional-properties=withSeparateModelsAndApi=true,modelPackage=models,apiPackage=api,supportsES6=true -o ./src/generated/api-client"
  }
}

openapi-generator-cli の generate コマンドのオプションについて説明します。

ジェネレーターとして typescript-axios を指定します。

1
-g typescript-axios

入力の API 仕様書として ./dressca-api.json というファイルを指定します。

1
-i ./dressca-api.json 

以下のプロパティを追加します。

  • withSeparateModelsAndApi=true :model と API を別クラス・別フォルダーに配置する
  • modelPackage=models:model :クラスのパッケージ名を「models」に設定する
  • apiPackage=apiAPI クラスのパッケージ名を「api」に設定する
  • supportsES6=true :ES6 に準拠したコードを生成する
1
--additional-properties=withSeparateModelsAndApi=true,modelPackage=models,apiPackage=api,supportsES6=true

生成されたコードの出力先を ./src/generated/api-client に設定します。

1
-o ./src/generated/api-client

クライアントコードの生成⚓︎

ターミナルで以下のコマンドを実行します。

1
npm run generate-client

オプション -o に定義した出力先へ、クライアントコードが生成されます。

クライアントコードの削除と再生成

openapi-generator-cli の generate コマンドでは、 OpenAPI 仕様書の変更によって不要になった既存のクライアントコードは自動で削除されません。 そのため、既存のクライアントコードを一度削除してからクライアントコードを生成するように設定しています。

クライアントコードの設定⚓︎

./src/api-client/index.ts という設定ファイルを作成し、以下のように記述します。

index.ts
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import axios from 'axios';
import * as apiClient from '@/generated/api-client';

function createConfig(): apiClient.Configuration {
  const config = new apiClient.Configuration({
  });
  return config;
}

const axiosInstance = axios.create({});

const defaultApi = new apiClient.DefaultApi(createConfig(), '', axiosInstance);

export { defaultApi };
  • apiClient.Configuration : api-client の共通の Configuration があればここに定義します。プロパティの詳細は こちら を参照してください。
  • axios.create : axios インスタンスを生成し、共通の設定をカスタマイズします。詳しくは 公式ドキュメント を参照してください。

このファイルでは、 api-client や axios 共通の設定をします。

  1. src/generated/api-client/api に自動生成された APIimport します。
  2. 上記の例の DefaultApi と同様に apiClient.XxxApi(createConfig(), '', axiosInstance) コンストラクターでインスタンスを生成します。
  3. 生成したインスタンスを export します。
BaseAPI のコンストラクター
  • BaseAPI(configuration?: Configuration, basePath?: string, axios?: AxiosInstance)

BaseAPI は OpenAPI Generator で自動生成されるコードの base.ts に含まれるクラスです。 各 API が継承している BaseAPI コンストラクターの引数に api-client の共通設定、ベースパス1、 axios インスタンスを設定することで、 API に関するグローバルな設定を適用します。

OpenAPI Generator で生成されたクライアントコードはデフォルトで OpenAPI 仕様書の URL が設定されます。 開発環境やモックで API サーバーなしでアプリを起動するためには、アプリレベルでエンドポイントを設定する必要があります。 Vite では /api のような相対パスに対して異なるエンドポイントの設定ができ、これを有効にするためには、 BaseAPI コンストラクターの第 2 引数のベースパスを空文字で上書きする必要があります。

base.ts
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
export class BaseAPI {
  protected configuration: Configuration | undefined;

  constructor(configuration?: Configuration, protected basePath: string = BASE_PATH, protected axios: AxiosInstance = globalAxios) {
    if (configuration) {
        this.configuration = configuration;
        this.basePath = configuration.basePath ?? basePath;
    }
  }
};

  1. ベースパスは https://www.example.com のようなリンク先の基準となる URL です。