こんにちは、デジタルイノベーションラボの飯島です。 今回は、OpenAPI を利用した開発とデプロイまでのフローをざっくり紹介します。
アプリケーション構成
バックエンドは Kotlin + SpringBoot, フロントエンドは TypeScript + React になります。 バックエンドが用意した API をフロントエンドが叩く、一般的なアプリケーションです。
フロー
1. OpenAPI 定義出力用の Interface を実装したコントローラーを作成
簡単なサンプルですが、以下のような Interface を作成し、implement してコントローラーを作成します。
@Tag(name = "UserCreate", description = "ユーザーの登録") interface UserCreateController { @Operation(summary = "ユーザー登録") @ApiResponses( ApiResponse(responseCode = "200", description = "登録成功"), ) fun create(user: User): HttpResponse } data class User(val name: String)
実装クラスに直接アノテーションを記載しても良いのですが、API 定義と実装が混在すると可読性が下がるため、Interface を分けています。
アノテーションはspringdoc-openapiで提供されているものを使っています。
2. Interface から OpenAPI 定義の yaml ファイルを生成する
openapi-generator gradle plugin を使用し、Interface から OpenAPI 定義の yaml ファイルを生成します。
3. 生成された yaml ファイルから、フロントエンド用のコードを生成する
OpenAPI Generator を利用して、バックエンドの API を呼び出すための TypeScript コードを生成します。 生成されたコードの内部で使用される Http client については、axios や fetch, ajax など複数の中から選択できます。 docker での生成にも対応しているので、バックエンド側で生成した openapi.yml を引数に generator を実行します。
4. 生成された API 呼び出しコードを利用してフロントエンドをコーディングする
React で画面を作り、3 で生成されたコードを使用してバックエンドとやりとりするようにします。 以下のコードでは、UserCreateApi, createConfiguration, ServerConfiguration がそれぞれ自動生成されたコードになります。 先ほどバックエンドの Interface に定義した create メソッドが UserCreateApi に用意されています。
const api = new UserCreateApi( createConfiguration({ baseServer: new ServerConfiguration(url, {}), }) ) api.create({ name: "taro" })
生成されたコードも TypeScript なので、型安全に使用することができます。
5. Slack からデプロイする
弊社ではほぼ全てのプロジェクトが Slack からデプロイできるようになっています。 動作確認などで検証環境にデプロイする用にデプロイマン、本番環境にリリースする用にリリースマンという bot を作ってあるので、コマンド一つで GitHub から簡単にデプロイすることができます。
最後に
バックエンドの API 定義箇所とフロントエンドの呼び出し箇所は、受け渡すデータは同じなのに言語が違うことで書き方が変わってくるため、こうして自動化できるとコーディングがかなり楽になります。 open-api generator の具体的な使い方などはまた別の機会に記事にしたいと思います。