Kotlin/Nativeでシングルバイナリから起動するHTTP APIを作る
はじめに
最近話題(?)のKotlinを趣味で書いていますが、(Javaとの親和性はもちろん)モダンで簡潔な記法が多く、非常に書きやすい言語だと感じています。
上記のように魅力的な言語ですが、サーバーサイドKotlinというとJVMを使用するイメージが強く、運用の際にはどうしてもJVMの知識が必要です。
そこでKotlinコードから実行可能なシングルバイナリを吐けないかと考え、Kotlin Nativeという技術に関して調査してみました。
Kotlin Native とは
簡単にいうと、Kotlinのコードをネイティブバイナリにコンパイルする技術です。
内部ではLLVMベースのコンパイラバックエンドが用いられ、出力されたバイナリの実行においてJVMは当然不要です。
想定される用途
Kotlin NativeはKotlin Multiplatform(クロスプラットフォーム間でのアプリ開発に使用される技術)に使用されており、想定される用途として、AndroidとiOS間の共通モジュール実装などが挙げられます。
Kotlin multplattformを使用したpjのアーキテクチャ概要
Web APIの構築は?
ではKotlin Nativeを用いて実行可能なシングルバイナリから起動するAPIを構築できないか?と調査したところ、下記の選定で目処がたったため実装しました。
種別 | 選定結果 (2023/2現在) |
---|---|
Web FW | Ktor (100% Kotlinの軽量FW) |
永続化 FW | SQLDelight |
DB | SQLite |
実装
ここでは本PJ特有の注意点に絞って解説します。
サーバーを起動するコード
以下の2点を満たす必要があります。
- Ktor組み込みの
embeddedServer
関数でサーバーを起動 - リクエスト処理にはCIO engineを使用する
fun main() {
embeddedServer(CIO, port = 8080) {
...
}.start(wait = true)
}
永続化FW(SQLDelight)の設定
ディレクトリ構成に注意点があります。
SQLDelightでは、発行されるクエリを.sq
ファイルに記述しますが、本PJではcommonMain/sqldelight
ディレクトリ以下に配置する必要があります。[1]
ビルド時の設定
SQLite用のライブラリをリンクする設定が必要です。[2]
apiTarget.apply {
binaries {
executable {
entryPoint = "com.example.main"
linkerOpts.add("-lsqlite3") // <- リンカに渡されるオプションを追加
}
}
}
実装結果
これまでの調査から簡単なWeb APIを実装することができました。
レコードのCreate、Read、Deleteが可能ですが、排他制御に関しては考慮していません。
動作イメージ
実装を通して感じたメリデメ
メリット
シングルバイナリの手軽さ
実行可能なシングルバイナリ形式でビルドされるため、追加でランタイムを整備する手間が省けます。
またアプリを起動する際、コンテナに出力されたバイナリを配置すれば、とりあえず起動できるため、コンテナを用いたアーキテクチャと特に親和性が高いと予想できます。
Java経験者に馴染みやすくモダンな文法
Javaでは互換性の問題から導入が見送られた機能等、モダンで簡潔な記法が使えるため、配列操作などをシュッと記述できます。
デメリット
動作するライブラリが少ない
まだまだ発展途上の技術のため、Kotlin on JVMには対応しているがKotlin Nativeでは動かないライブラリが大量に存在し、Ktor公式ですらKotlin Nativeに未対応のライブラリが存在しています。
今回の例として、リクエストログを出力する機構は自作しました。[3]
ビルド時間
手元のM2 MacBook Air環境でビルドしたところ、下記のような結果となり、(筆者は他の言語で比較できないですが)少なくとも早いとは感じませんでした。
$ time ./gradlew apiMainBinaries
...
./gradlew apiMainBinaries 0.84s user 0.11s system 1% cpu 58.047 total
$ time ./gradlew apiMainBinaries
...
./gradlew apiMainBinaries 0.85s user 0.12s system 1% cpu 52.769 total
ネットに情報が少ない
日本語の情報は皆無で、英語ですら検索にヒットしない場合があります。
学習コスト
Java経験者に馴染みやすい文法とはいえ、KotlinとKotlin Native両方の知識が必要です。
※しかしKotlin以外の言語に移行する際でも、多かれ少なかれ学習コストは必要
まとめ
今回はKotlin Native + Ktor + SQLiteで簡単なAPIを作成しました。
まだまだ発展途上の技術ですが、今後のKotlinに期待できるような体験ができたため、趣味でも触っていきたいと思います。
以上。(※記事への指摘歓迎)
参考
Discussion