【GMOリサーチではエンジニアを募集中です】採用情報はこちら!

Server side Kotlin で社内APIを開発した〜使い方(入門編)便利Tips〜

Server side Kotlin で社内APIを開発した〜使い方(入門編)便利Tips〜

はじめまして。システム部の岡崎です。

現在はCTOオフィスでビックデータのデータ集めに関する基盤整備や、アプリケーションの開発を担当しています。

タイトルにある通り、今日はServer side KotlinでAPIを開発した話について、そして自分が実際にKotlinを使っていて便利だと感じたことや、発見したことについて説明していこうと思います。

Kotlinを使うことになった経緯

社内利用のAPIを作ることになり、 spring-boot + myBats + Kotlin を提案したところ見事採用されました。

なぜKotlinを使ってみようと思ったかというと。

そもそもWeb APIを作成することになった際、下記3つの選択肢がありました。

  • Cake PHP
  • Java Spring-boot
  • Kotlin  

以前 Spring-boot+myBatis+Java でバッチの開発をしたときに、Springが便利!なことに気づき今回もそれに乗っかって行こうと考えたのですが…。

「一度Kotlinを使うとJavaには戻れない・・・」といった声を前々から(ネット上で)目にしていたこともあり、どうせなら、モダンと呼ばれるKotlinに挑戦してみたい!NullPointerException撲滅したい!と思ってKotlinの使用を提案してみた、というのがキッカケです。

もちろん、Kotlinという、我々GMOリサーチシステム部にとって新しい言語を採用するにあたって乗り越えるべきハードルも多々ありました。

  • 使用する言語が増えると、その分メンテナンスコストが増える
  • 社内エンジニアに対する教育コストがかかる
  • Kotlinという言語の将来性の検討(サポート終了の可能性等)
  • Kotlinでうまくいかなかった場合初めからJavaで書き直す必要がある・・・等

これらの課題に対してどのように向き合うべきか社内で検討した結果、

『メンテ、教育コストがかかるのは仕方がないので割り切る。導入すると決めた自分たちがある程度の苦労を要するのは覚悟の上!頑張ることと引き換えにチャレンジできる権利を手に入れるんだ!!!

という若干スポ根漫画のような結論に至りました(だって、それでも挑戦したかったんだ…)。

とはいえ現実問題として、Kotlinという言語が今後廃れてしまっては困ります。

この問題に関しても、Androidに選定されている&サーバーサイドでも使われる機会が増えてきていたり、JetBrainsによる開発であったりということから、ある程度信頼性の高い(これから更に流行っていくであろう)言語であると判断しました。

また、実際にKotlinで書いてみてうまく行かなかったらどうするかという問題について。

もちろん最初からJavaで書き直すことになりますが、ダメな場合は割と早い段階でわかるだろうと考えていた、かつ、KotlinからJavaはIntelliJでソースコードを一括置換することができる!ということが後押しとなり、ここのハードルも乗り越えることができました。

ということで、長くなってしまいましたがここまでが今回Kotlinを使ってAPI開発を行った経緯になります。

自分は今回初 Kotlin であったため、実際の開発の中で「これ便利だな」と思ったところや、ハマった末に解決した事象などを下記に書いていきます。

Kotlinという言語について

簡単にではありますが、Kotlinという言語について軽く説明を入れておきます。

* Kotlin とは

 Android Native Application の標準開発言語。コンパイル後に出力されるコードはJavaバイトコードも出力できるので、サーバサイドでJavaVM上で動作させることができる。

* Spring boot(Sprong framework) とは

  Java界隈では非常に有名な アプリケーションフレームワーク。WEB関連やら、DIやら、ORマッピングやら様々な機能、モジュールが存在する

* myBatisとは

 * これもJava界隈では非常に有名な O/R マッパー

Kotlin入門(感想と便利Tips)

それでは、まずはKotlinを実際に使ってみて便利だと思ったことや、分かったことご紹介していきます。

1. val と var

  • 明示的に変数の書き換え「可 (var)」「不可 (val)」を宣言したい
  • できる限り val(書き換え不可)で宣言し、どうしても必要なときだけ var にする
  • ちなみにval で宣言した変数に誤って再代入しようとした場合、コンパイラでエラーにしてくれるのでたのもしい

2. 型推論

  • 冗長に型宣言をする必要がない(これがないだけでもソース書きの快適さが増す!)

3. nullable

  • 基本的にNullの代入は許容されない
  • NullPointerException 撲滅!(したい。。)

4. もし Null だったら初期値代入の書き方が簡潔にできる

  • myBatis を使っていると Nullを許容していないのにNullになってしまう場合がある
  • 下記のような書き方で 簡潔に記述できる

5. constructor の宣言と property の宣言を同時に書ける(data class)

  • 例えば myBatis の Domain class の宣言が簡潔にできる
  • equals メソッドを自動生成してくれるところも地味に便利

6. 定数を定義する際記述がちょっと違う

  • 定数はこんな感じで定義
  • これで static final String などで定義していた定数を表現可能


Spring + Kotlin

続いてSpring + Kotlin 編

1. Autowired するとき

  • Autowired でインスタンスを生成したい場合、初期値を設定できないため 普通 var で定義できない。なので、以下のような定義をする必要あり

2. log4j で Logを出力する

  • java のときは @sl4j annotation で済んでいたのだが、今回は使えない。ので、以下の方法でlogを出力を実装した
  • logger.kt を定義(importできるどこかにおいておく)
  • logを使用したいclassで以下で利用する


myBatis + Kotlin 編

さらにmyBatis + Kotlin 編

Java でmyBatis を使ったときとここが違うなーと思ったところです。

1. myBatis + Kotlin で Nullable が無視される問題

  • myBatis で落とし穴
  • Select結果が1件のなにかである場合のMapperの戻り値で、検索結果に結果が0件であった場合、たとえNullable宣言していたとしても、Nullが返る

例えば

Mapper

Service

なので、場合によっては下記のように宣言して Nullが帰ってくるかもしれないことを考える必要あり。

2. プレイススホルダの書き方が変

  • Kotlinではすでに文字列のプレイスホルダが存在するため、Mapper などで @Select Annotation のプレイスホルダを普通に書けない。なので特殊な書き方をする必要あり。

だめパターン

OKパターン

Select Annotation に ‘${id}’ という文字列を渡す必要があるため下記のように記述する

3. Domain class を data class で宣言したい。

  • 単純に data class として宣言しただけだと Mapperのメソッドを実行した時点でエラーになる。
  • myBatis は Domain class のインスタンスを作るときに 引数無コンストラクタを呼ぶためそこでエラーとなる。
  • ただし、data class そのままでは引数なしのコンストラクタを許容してくれない
  • 解決方法は以下(gradle を使っていることを前提として説明する)

gradle.build.kts の plugins へ以下を追加する

domain class へ @Data annotation を追加して data class を宣言する

4. マルチスキーマを定義する

WEB検索してもあまり参考例が出てこないので、複数のスキーマを使う際のやり方を記載してみる。

1.ディレクトリ構成

2.configration クラスを定義する
スキーマの数だけこのclassを作る
それぞれ内容はほぼ同じで @Promary annotation だけ 1つの configration class 追加する

3.Application class で読み込む

4.これで各スキーマディレクトリ下に作られたMapperは所定のスキーマに接続されて動作するようになる

Kotlinを実際に使ってみた感想

今回自分が初めてKotlinを使ってみて、やはり「とても書きやすい!」と感じました。

冗長な宣言などが必要なく、またIntelliJの補完機能もあり、思考をコードに落とすのがこれまでのどの言語より気持ちよかったです(まさにモダン!)。

また、いざとなったらJavaのライブラリをそのまま使える点も安心して使える要因の一助になりました。

これからもっとKotlin用のライブラリが充実してくれば、myBatisのときのような Null安全が崩れる状態も起こりづらくなるのかなと。

それまでは、ある程度は気配りが必要になるのでないかと思います(にしても気を使う部分はかなり減っているステキ)。

開発ブログカテゴリの最新記事