はじめまして、人事の友永です。エムスリーのエンジニアが日々どのようなチャレンジをしているのか、もっと皆様にお届けしたい!という思いから、インタビューシリーズを始めることになりました。
エムスリーのプロダクトは医療従事者向けのものが多く (注)、 実際にユーザーとして利用することが難しいこともあり「どんなプロダクトを作っているのかイメージしにくい」という声をいただいていました。そこで今回は、インタビューを通じてエンジニアの取り組みや普段の雰囲気もお伝えしたいと思います!
注) コンシューマ向けプロダクトもあります
第1回目は医師・薬剤師キャリアチームで行ったサーバサイドKotlin導入事例についてお話しを伺います。
友永: まず始めにプロジェクトの生みの親である前原さん、簡単に自己紹介お願いします。
前原: エムスリーには4年前に入社し、現在は医師・薬剤師のキャリア支援事業のエンジニアチームリーダーを担当しています。担当している事業の事業規模は年間売上高100億円超と急成長しているのですが、一方で扱っているシステムは10年前の技術スタックをベースにしているなど老朽化が進んでおり、開発効率が落ちている点が問題でした。
これをなんとかしたいと思い、2017年4月にリニューアルプロジェクトを立ち上げました。 モノリシックなJavaの独自フレームワークで作られていたシステムを、APIサーバとフロントに分離し、APIサーバをKotlin(Spring Boot)・フロントをRuby on RailsとVue.js(Nuxt.js)でリニューアルするというものです。
友永:
リニューアルプロジェクトを一緒に進めている滝安さん、鈴木さんも自己紹介をお願いします。
滝安: 2017年8月の入社です。前職はファイルストレージの開発というWeb開発とは全然違うことをしていました。エムスリーへ入社後、医師キャリアリニューアルを担当し、いきなりKotlinを使ってWeb開発を行いました。前職ではCを業務で使うことが多かったですが、Kotlin習得にあたっては特に違和感はなく便利な言語だなという印象でした。ちなみに、個人的に好きな言語はGoで、もくもく会を開催しています。
鈴木: 2017年11月に入社しました。前職ではRubyでの開発がメインでしたが、技術的に新しいことがやりたいと思っていたところ、今回のリニューアルプロジェクトで何かできそうと感じエムスリーに入社しました。入社後はサーバサイド:Kotlin、フロント:Vue.js(Nuxt.js)でサーバ側もフロント側の開発も行っています。私は薬剤師キャリア事業のリニューアルプロジェクトを担当しています。
友永:
サーバサイドにKotlinを導入した経緯など教えてください。
前原: 私達のチームでは先ほどお話したモノリシックなJavaアプリケーションだけでなく、Ruby on Railsも多く利用していたので、全てRuby on Railsでリニューアルするという選択肢もあったのですが、複雑なビジネスロジックが集まるサーバーサイドは型がある言語でカッチリ書きたいという思いが以前からありました。
型がある言語として、Java、Scala、Goなどを複数の項目で比較検討しましたが、その中でもKotlinはRubyとsyntaxが似ていて、チームのRubyエンジニアがキャッチアップしやすそうだと感じた点がKotlinを採用した理由として大きかったです。
また、サーバサイドにKotlinを導入したという事例は当時国内ではあまり見当たらず、先駆的なチャレンジをすることで、「技術的チャレンジを好む仲間を集めたい」という思いもありました。国内の導入事例は少ないものの、Kotlinでプロトタイプを作ってみたり、JavaのフレームワークであるSpringがKotlinを公式でサポート予定と発表しているのを見て、これはイケるぞと判断しました。
友永: RubyエンジニアがKotlinを触ってみてどうでしたか?
鈴木: まず、syntaxがRubyと似ています。特にリストに対する操作は似ていたのでキャッチアップしやすかったです。 またKotlinは静的型付け言語ではありますが型推論が効くので、型を書かない動的型付け言語のRubyと比べても面倒臭さはなく抵抗はなかったです。
前原: KotlinとRubyで書いたコードを並べて比べたことありますが、リスト操作のsyntaxが非常に似ており、キャッチアップしやすかったですね。
参考:
10年前のレガシーシステムをサーバーサイドKotlinでフルリニューアルしている話 #jjug_ccc #ccc_g2 // Speaker Deck
滝安: 私はプライベートでRubyを使っていました。Rubyは1人で開発する分には素早く書けていい言語だけど、大規模に開発する場合は型があったほうが壊れにくいのでいいかなと。初めてKotlinでNull Safetyな言語に触れたのですが、NullPointerExceptionが発生しうる書き方をするとコンパイルエラーになってくれるので、安心して書けるなと思いました。
友永:
Kotlin導入のメリットについて教えてください。
前原: 当初の想定どおり、RubyとKotlinはsyntaxが似ているので、Rubyエンジニアのキャッチアップが早く、かつ型やNull Safetyのおかげで堅牢に書けるというのはとてもよかったです。
また、エムスリーではRubyかJVM系のプロジェクトが多いため、社内の共通ライブラリは基本的にRubyとJava版が提供されています。KotlinはJVM系の言語の為、Javaのライブラリを使える。つまり、社内の共通ライブラリをKotlinから呼べる、これもよいところでした。社内のライブラリだけでなく、オープンソースのJavaライブラリも使えるため、言語周辺のエコシステムが既に存在しているというのもよかったですね。
鈴木: ライブラリはJavaのものであれば使えるものが多いです。多少Kotlin用のモジュールを入れないと動かないというものもありますが、Kotlinをサポートしていく方針のものも多いので、あまり心配しなくていいかなと。Spring Bootも開発途中に2.0がリリースされましたが、特に問題なくアップデートできました。
前原: 数ヶ月前に第1段階目のリリースを完了させたのですが、Kotlin起因のバグはなかったですね。
滝安: KotlinよりSpring Bootの話ですが、レイヤードアーキテクチャにマッチしていたのが良かったですね。冗長に書かなくてもアプリケーションフレームワークがケアしてくれるので無駄がない。その分学習コストが高いデメリットもあったけど笑 Kotlinはそこに乗っかれるのがよかったです。
鈴木: Data Class がよかったなと思います。シンプルな記述で、コンストラクタとプロパティが記述できるので、パラメータを初期化し忘れるとかそういった単純なミスが防げるなと、Kotlinをやってから他の言語を触ると特に感じます。
今回リニューアルしているシステムは、歴史も長くDBのスキーマは正直あまり綺麗な状態とは言えない状態でしたし、ビジネスロジックもいろんなところに散らばっている状態だったのですが、DDDの考え方を取り入れたり、レイヤーをきちんと定義したことで、今後の変更がし易い状態になったかなと思います。
KotlinでDDDやる事例はまだなかったので、Scalaで既にやられている方の資料を読んだり、実践ドメイン駆動設計を読んだりしました。ユースケースがみんな違うので自分達はどうしていくべきなのか考えるのは難しかったですね。
前原: Data Classは凄くよいなと思いました。Data Classのcopy()関数を使うと、既存オブジェクトのプロパティの一部だけ変更して新しいオブジェクトを作ることが出来るのですが、これを用いると、一つのテストデータの雛形から様々なテストデータを生成する、といったことが簡単にできるので、重宝しました。
友永:導入時の注意点やハマったことについても是非教えてください。
前原: Kotlinの拡張関数の使い所には迷いました。拡張関数は便利だけど、やたらめったら使うとぐちゃぐちゃになるので、結果として私たちのチームでは本当に必要な時以外は使わないと定めました。
鈴木: 使いどころが難しいですね。Rubyでモンキーパッチを当てて拡張していくのは、メンテナンスを考えるとなかなかカジュアルにできませんが、Kotlinの場合はコードで追えてしまうので逆に使い所に悩む。
滝安: レイヤーで責務をまとめているのに、関係ないところで書き換えられちゃうと、その構造の意味が薄れてくるので、あんまり使いたくなかったですね。そもそも自分らで書いているところなんだから、拡張じゃなくで大元を直しなよ、と笑
前原: 私たちは拡張関数の使い所を、テストコードで既存のテストライブラリにちょっと便利なメソッド生やしたい時に使うくらいにとどめました。MockMvcBuildersに便利な拡張関数生やしたりとか。その場合範囲がテストの中にとどまるし、メリットの方が大きいと考えました。
鈴木: gRPCを使っていた時に、LocalDateTimeをgRPC用のフォーマットに変える時は使いどころかなと思い使ってみました。プリミティブなというか元々あるクラスを拡張する時は使いどころかもしれないですね。
拡張関数でアプリケーションのドメインを生成していたりするのはちょっと微妙かなと思いますが、単純なフォーマット変換などコンテキストを絞って使うのはアリかなと。
滝安: アノテーション周りははまりどころが多かったです。SpringFoxというライブラリを使って、クライアントライブラリを自動生成しているのですが、関数名がちょっと変わってライブラリが作られちゃう、例えばisAdminがis取れちゃって、adminになっちゃうとか。
他にも、バリデーションをかけるのにSpring Bootのアノテーションをつけて、うまく効かないというのもありました。これは、Kotlinは一回Javaに変換してからコンパイルされるので、変換した後だと思ったところにアノテーションがついていないのが原因でした。
鈴木: バリデーションでget:をつけていないと利かないというのもありました。利かないけど何も教えてくれないとか。モック系のライブラリがKotlinのNull Safetyで落ちるとか。マニアックなやつだと、enumのクラスでメソッドをoverrideしているときだけ起きるバグを踏みました。 それくらいですかね、エッジなバグ踏んだの笑
前原: ハマりどころがあったとしても、大概調べたら解決方法がでてくる程度のものでしたね。Javaのライブラリを使う時にたまにあるくらいで。モックのやつもワークアラウンドをこうすればいいというのも調べたら出てきました。
鈴木: 情報が徐々に増えてきていて、基本的に普通のユースケースで見つかるバグは誰かが潰しているか、ワークアラウンドがすぐ見つかる状況でした。
前原: サーバサイドでKotlinを使うケースはまだあまり聞かないけれど、AndroidでKotlinを使うケースはとても増えているので、知見がネットにもあがっていますね。
また、今回Kotlinを選択した大きな追い風として2017年のGoogle I/OでGoogleがKotlinをAndroidの開発言語として正式にサポートすると発表したことも大きかったです。困ったらKotlinのGithubのプロジェクトを調べれば色々出てくるし、どこにも情報なくて困るということは殆どありませんでした。
滝安: Javaの情報を頭の中で翻訳すればKotlinの情報になるので、そんなにそれ自体で困ることはなかったですね。あと、IDEがすごい強力というのもあります。下線がにゅーってなっているところの指摘通り書くときれいに書けます。
友永:
最後にサーバサイドKotlinを導入してよかったことをまとめてください。
前原: 私たちのプロジェクトではKotlinを使ってよかったし、正解だと思っています。また、これをきっかけに社内だけじゃなくて、社外で勉強会を開催して広がりができたのも非常によかったです。エムスリー主催で「どこでもKotlin」という勉強会をこれまで5回開催しましたが、社外の方にも多く登壇いただいくことで、情報交換ができました。サーバーサイドKotlinをやっている人、検討している人にもたくさん会うことで、共通の悩みを共有できました。実際、鈴木さん、滝安さんもこういったチャレンジを対外的に発表していたから入社してくれたのかなと笑
鈴木: Kotlinでサーバサイド開発を行う事例は、当時あまり聞いたことがなかったし、技術的に面白そうだと思いました。
滝安: 私は個人的にはGoが好きだけど、それ以外の言語が嫌なわけではなくて、新しいことに技術を使って挑戦できるのがいいなと思いました。Kotlinというイマドキの技術を使って抜本的なリニューアルをしていくのは、面白そうだなと。他社のエンジニアと話すときにサーバサイドKotlinやってる、と言うとびっくりされることもあって、技術だけ見ても新しさはありますかね。
前原: 冒頭に話しましたが、今回のプロジェクトでは、技術的なチャレンジをすることで、チャレンジが好きな仲間を集めたいという思いがありました。それを魅力に感じてくれたのれあればよかったです!現在では、社内の他チームでもKotlin採用事例が増えてきていますしね!
ということで、Kotlinで開発したい人、一緒に働きましょう!!!