2022 年 12 月 14 日現在、SpringBoot v3 がリリースされています。
しかし、OpenAPI Generator v6.2.0 では Kotlin-Spring に対して SpringBoot v3 は非対応です。
現在、PR が作成されています。v6.3.0 でマージが予定されているので、待ちましょう。
本記事は、OpenAPI Generator v6.2.0 と SpringBoot v2 における内容です。
本記事では OpenAPI Generator を用いて openapi.yaml から Kotlin(Spring Boot)のソースコードを自動生成する方法を紹介します。
以下の構成にしたがって進めていきます。
本記事で作成したサンプルコードは以下に載せています。
https://github.com/Msksgm/openapi-generator-sample
OpenAPI Generator についてOpenAPI Generator とは、OpenAPI Specification(以下、OpenAPI)をもとに、ソースコードを自動生成するツールです。
OpenAPI Generator を利用することで、スキーマ駆動開発を実現しやすくなります。
https://github.com/OpenAPITools/openapi-generator
OpenAPI ベースでソースコードを生成できるため、以下のメリットがあります。
OpenAPI と OpenAPI Generator についてほかにも特徴がありますが、以下の記事を参考にしたので、詳細なことは以下を参考にしてください。
https://qiita.com/amuyikam/items/e8a45daae59c68be0fc8
また、記事に引用されていた以下の資料は、OpenAPI Generator の Contributer の方が作成されたものです。
OpenAPI の歴史と OpenAPI Generator が制作された経緯を紹介しており、非常に興味深かったのでぜひ一読してください。
https://speakerdeck.com/akihito_nakano/gunmaweb34
Kotlin(Spring Boot)に導入Kotlin に導入する際には、build.gradle.kts 記述が必要なため本項目で解説します。
Kotlin で導入すると、Controller に使用する interface と data class が生成されます。interface はエンドポイントのルーティング、メソッド、ステータスコードなどが定義されます。同様に、data class はリクエストとレスポンスの型が定義されています。
openapi.generator プラグインを導入するほかに、前提として以下のように設定します。
概要 内容 生成される interface のエンドポイントのまとめ方は、OpenAPI の tags 準拠 デフォルトだと API のパスをパースするため 生成されたソースコードは、Git で管理しない build/ 配下に生成して、builld.gradle.kts の設定で import できるようにする compile するたびにソースコードを自動生成する 意図しない変更があったときに、ビルドを停止するため !Git で管理しない理由は自動生成したファイルを編集すると、次に自動生成したタイミングで簡単に上書きや、コンフリクトが発生するためです。
また、自由でに修正できる状態だと、ソースコードがスキーマファイルである OpenAPI から乖離します。結果、スキーマファーストな開発ができなくなってしまいます。
具体的に build.gradle.kts に何を記述するのか解説します。
長くなったので、項目(plugins、dependencies、task、そのた)ごとに分割しました。
まず、OpenAPI Generator が提供している、openapi.generator
を記述します。
build.gradle.kts
plugins {
id("org.openapi.generator") version "6.2.0"
}
dependencies
生成したソースコード内で利用されているライブラリを記述します。
src/から参照したり、ビルド時にも参照するため、記述しないとビルドが落ちます。
build.gradle.kts
dependencies {
compileOnly("io.swagger.core.v3:swagger-annotations:2.2.4")
compileOnly("io.swagger.core.v3:swagger-models:2.2.4")
compileOnly("jakarta.annotation:jakarta.annotation-api:2.1.1")
implementation("org.springframework.boot:spring-boot-starter-validation")
}
task
./gradlew に task を追加します。
追加するタスクは以下の表の通りです。
また、task の追加設定で、コンパイル時にgenerateApiServer
の実行するように設定します。task<GenerateTask>("generateApiServer")
に記述してある、apiPackage.set
とmodlePackage.set
のパスは各自のパスを指定してください。main/kotlin
からパスを指定します。
build.gradle.kts
import org.openapitools.generator.gradle.plugin.tasks.GenerateTask
task<GenerateTask>("generateApiDoc") {
generatorName.set("html2")
inputSpec.set("$projectDir/openapi.yaml")
outputDir.set("$buildDir/openapi/doc/")
}
task<GenerateTask>("generateApiServer") {
generatorName.set("kotlin-spring")
inputSpec.set("$projectDir/openapi.yaml")
outputDir.set("$buildDir/openapi/server-code/")
apiPackage.set("com.example.yourapp.openapi.generated.controller")
modelPackage.set("com.example.yourapp.openapi.generated.model")
configOptions.set(
mapOf(
"interfaceOnly" to "true",
)
)
additionalProperties.set(
mapOf(
"useTags" to "true"
)
)
}
tasks.compileKotlin {
dependsOn("generateApiServer")
}
その他
build されたソースコードを import できるようにする設定も、build.gradle.kts に記述します。
build.gradle.kts
kotlin.sourceSets.main {
kotlin.srcDir("$buildDir/openapi/server-code/src/main")
}
以上で導入完了です。
ソースコードの自動生成導入したので、どのようにして自動生成するのか確認します。
!自動生成する部分だけを手元で確認したい場合は、以下の手順で確認可能です。
./gradlew generateApiServer
または、gradle タブ->other->generateApiServer を押下ソースコードの生成もとになる、OpenAPI を作成します。本記事では v3.0.2 で作成しました。
メタ情報(openapi、info、servers)、エンドポイント(paths)、コンポーネント(components)から構成されます。
具体的な記述方法について触れませんので、公式ドキュメントを参照してください。
https://spec.openapis.org/oas/v3.0.2
本記事で作成した OpenAPI。openapi.yaml
openapi: "3.0.2"
info:
title: OpenAPI Generator Kotlin Sample
description: OpenAPI Generator を用いた自動生成のサンプルコードです
license:
name: MIT License
url: https://opensource.org/licenses/MIT
version: "1.0"
servers:
- url: /api
paths:
/customers:
get:
tags:
- Customer
summary: カスタマーの一覧取得
description: DB に登録されているカスタマーを全て取得する
operationId: List
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/MultipleCustomersResponse'
components:
schemas:
Customer:
required:
- first_name
- last_name
type: object
properties:
first_name:
type: string
last_name:
type: string
MultipleCustomersResponse:
required:
- customers
type: object
properties:
customers:
type: array
items:
$ref: '#/components/schemas/Customer'
コマンドの実行
以下のコマンド(または、intellij の gradle タブ->other->generateApiServer)でソースコードを自動生成できます。
生成されたソースコードは、build/openapi/server-code/src
配下に存在します。
./gradlew generateApiServer
生成されたソースコード
中身を確認すると、以下になっています。
OpenAPI がソースコードに反映されたことがわかりました。
CustomerApi.kt
@Validated
@RequestMapping("\${api.base-path:/api}")
interface CustomerApi {
@Operation(
summary = "カスタマーの一覧取得",
operationId = "list",
description = "DB に登録されているカスタマーを全て取得する",
responses = [
ApiResponse(responseCode = "200", description = "OK", content = [Content(schema = Schema(implementation = MultipleCustomersResponse::class))])
]
)
@RequestMapping(
method = [RequestMethod.GET],
value = ["/customers"],
produces = ["application/json"]
)
fun list(): ResponseEntity<MultipleCustomersResponse> {
return ResponseEntity(HttpStatus.NOT_IMPLEMENTED)
}
}
また、以下のコマンドによって、API ドキュメントの生成も可能です。
生成された API ドキュメント ./build/openapi/doc/index.html 。
生成された API ドキュメント
生成した interface を実装することで、REST API を作成します。
interface の実装生成した interface の実装方法は以下になります。
build.gradle.kts の設定によりbuild/
配下のファイルを import 可能なことがわかります。
非常に簡潔な実装になり、開発者が実装する部分はほとんどないことがわかります。
CustomerController.kt
package com.example.openapigeneratorsample.controller
import com.example.realworldkotlinspringbootjdbc.openapi.generated.controller.CustomerApi
import com.example.realworldkotlinspringbootjdbc.openapi.generated.model.Customer
import com.example.realworldkotlinspringbootjdbc.openapi.generated.model.MultipleCustomersResponse
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.RestController
@RestController
class CustomerController : CustomerApi {
override fun list(): ResponseEntity<MultipleCustomersResponse> {
return ResponseEntity(
MultipleCustomersResponse(
customers = listOf(Customer("Alice", "example01"), Customer("Bob", "example02")),
),
HttpStatus.OK
)
}
}
動作確認
一応動作確認します。
以下のコマンドでレスポンスが戻ってくることが確認できたら完了です。
curl -X GET \
-H "Accept: application/json" \
"http://localhost:8080/api/customers"
まとめ
本記事では OpenAPI Generator を利用して、Kotlin(Spring Boot)で API のソースコードを自動生成する方法を紹介しました。
OpenAPI Generator によってスキーマ駆動開発による並行開発や開発者が注力する領域をドメインに限定できます。
さまざまな言語で利用できるため、新規開発で新しい言語を導入する敷居も下がるので、ぜひ利用してみてください。
https://blog.onk.ninja/2017/09/21/schema_first_development
https://qiita.com/amuyikam/items/e8a45daae59c68be0fc8
https://speakerdeck.com/akihito_nakano/gunmaweb34
https://ackintosh.github.io/blog/2018/05/12/openapi-generator/
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4