QUO CARD Digital Innovation Lab Tech Blog

クオカード デジタルイノベーションラボの技術ブログです

OpenAPI を利用した開発フロー

こんにちは、デジタルイノベーションラボの飯島です。 今回は、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 の具体的な使い方などはまた別の機会に記事にしたいと思います。