DMM.comの、一番深くておもしろいトコロ。

DMM.comの課金プラットフォームにおけるサーバーサイドKotlin事情【Developers Boost 〜U30エンジニアの登竜門〜】

DMM.comの課金プラットフォームにおけるサーバーサイドKotlin事情【Developers Boost 〜U30エンジニアの登竜門〜】

はじめに

こんにちは!
プラットフォーム事業本部 ペイメントサービス部の北澤、柏熊です。
ペイメントサービス部では、DMM.comのあらゆるサービスを支える課金プラットフォームを提供しています。

そんな私達は、2018年12月15日に開催されたDevelopers Boostで登壇しました。今回は登壇内容を補足しつつ、皆さんにご紹介したいと思います。 

event.shoeisha.jp

登壇概要

登壇は「DMM.comの課金プラットフォームにおけるサーバーサイドKotlin事情」という内容でした。

speakerdeck.com

ペイメントサービス部では複数のプロダクトでサーバサイドKotlinを用いたAPI開発を行っています。その中で得た知見を共有することで、サーバサイドKotlinを採用するか判断に迷ってる人たちの参考になればと思い、発表しました。 

大きく以下3つの観点でお話しました。

  • なぜKotlinを採用したのか?
  • 実際に使って気づいた良い点・使いづらい点について
  • 採用した結果、どのような効果が得られたか? 

なぜKotlinを採用したのか?

採用した理由は3つあります。 

新しいことやってみたい

課金プラットフォームでは、理にかなっていれば技術選定が自由です!
KotlinはJavaと100%互換を謳っているので、Javaのライブラリを再利用できます。
また、Javaと比べて便利な機能が備わっており、コード量の削減が期待できるという点から、理にかなっていると判断しました。  

今後長く使える言語

Kotlinは2017年5月のGoogle IOにて、Androidの公式言語に採用されました。
また、KotlinはJetBrains社によって開発・メンテナンスされています。
このことから、言語自体がメンテナンスされなくなってしまい、プロダクトに悪影響を及ぼす可能性が低いと判断しました。  

Javaエンジニアにとって習得が容易

現在、課金プラットフォームの過半数がJavaエンジニアです。
KotlinはJavaとの互換性があり、IDEでのJava→Kotlin変換も可能です。
Javaを知っているエンジニアにとって習得が容易なため、負債となってしまうリスクが低いと言えます。


以上3つの理由から採用に至りました。 

実際に使って気づいた良い点・使いづらい点について

登壇ではJavaと比較して4つの良い点と、1つの使いづらい点をお話しました。
ここではそれぞれ、1つずつ抜粋してご紹介します。  

良い点: null safety

Kotlinは、NullPointerExceptionをコンパイル時に防ぐことができます。
Javaから来た人は結構イケてる! と、感じるのではと思います。 f:id:kashiwaguma-hiro_dmm:20181220145344p:plain上記例はごく簡単なものですが、 nullReturnMethod() が nullを返し、String型の変数に代入し、 toLowerCase()を呼び出しています。f:id:kashiwaguma-hiro_dmm:20181220145303p:plainJavaはもちろん、toLowerCase関数を呼び出す部分で実行時にNullPointerExceptionになります。
しかし、Kotlinは変数代入時にコンパイルエラーになってくれます!
これはこれで良いのですが、現実的にはnullを扱いたい場合があるため、このままでは困ってしまいます。f:id:kashiwaguma-hiro_dmm:20181220145417p:plainこれに対応するには、 変数の型へ「?」を付与します。
こうすることで、変数にnullが入る可能性を表現できます。
これにより、変数代入のときのコンパイルエラーは解消されます。 
f:id:kashiwaguma-hiro_dmm:20181220145439p:plainしかし、今度はtoLowerCase関数を呼び出す部分で、コンパイルエラーに変わります。
f:id:kashiwaguma-hiro_dmm:20181220145454p:plain
これを解消するには、safe call演算子を使います。
これを使うと、変数の中身がnull 以外の場合のみ、関数を実行するようになります。
(Javaのif文で null 判定し、null ではない場合にメソッド実行する処理と同じ)f:id:kashiwaguma-hiro_dmm:20181220145516p:plainまた、エルビス演算子を使うことで変数がnullの場合のデフォルト値を指定することもできます。
ちなみにJavaでも同じ処理を書くとKotlinと比較してコード量が多く辛いものになります…。f:id:kashiwaguma-hiro_dmm:20181220145537p:plain
大きな違いとしては、Kotlinではnullを扱う時にコンパイル時にチェックしてくれる点です。これによって、早く・安全に開発できるかなと思います。

使いづらい点: nullを扱うライブラリと相性が良くない

使いづらい点として、Nullを扱うライブラリとの相性が良くないという点を紹介します。テストコードでMockito*1を利用して一部の挙動をMock化する例をあげます。

今回の例ではデータベースからデータを取得するhistoryRepositoryをMock化します。
着目する点はMockito.any()がnullをreturnするところです。f:id:kashiwaguma-hiro_dmm:20181220150201p:plain先程あげたKotlinの便利なところでnull safetyを説明しましたが、Kotlinではnullを許容していない場合、例外になってしまうので正しくテストが実行できません。f:id:kashiwaguma-hiro_dmm:20181220150214p:plainこれに対応するため、私達はnullを考慮したライブラリである mockito_kotlin *2 を使用することで回避しました。もちろん、同様の処理を自作することでも回避可能です。

今回はMockitoの事例でしたが、他のJavaのライブラリでも同じことが言えるので注意が必要です。

実際に導入した結果どうなったか

続いて、実際にプロダクト開発に導入した結果どうなったかをお話します。 
f:id:kashiwaguma-hiro_dmm:20181220151529p:plain

課金プラットフォームでは約13%のプロダクトにKotlinを採用しています。Kotlinを採用しているプロダクトの例としてDMMポイントを操作するAPI(以降、ポイントAPI)を紹介します。 

ちなみに、DMMポイントとはDMMで1ポイント1円として利用できるポイントサービスです。詳しくは無料のマンガで紹介していますので、よろしければご覧ください!

book.dmm.com

DMMポイントは1ヶ月で70億円を売り上げ、500万リクエストを捌いている非常に大規模なプラットフォームです。
このDMMポイントを操作するポイントAPIの一部をKotlinでリプレイスしました。
リプレイス前は以下のような課題があり、リードタイムが長い状態でした。

  • 一般的でない技術を使用していることで改修コストが高い
  • レガシーなミドルウェアと強く結合していることで保守コストが高い

これらの問題を解決してリードタイムを短くするためにリプレイスを実施しました。 
f:id:kashiwaguma-hiro_dmm:20181220151811p:plain

全部で11種類のAPIのビジネスロジックを4名のKotlin未経験のエンジニアで開発しました。2ヶ月間という短い期間で開発できましたが、それはKotlinの採用理由にもあった、JavaエンジニアのKotlin学習コストが低いメリットを活かせた結果だと考えています。
また、Kotlinを採用したことでビジネスロジックのコード量を31%削減することに成功しました。コード量が減ったことで可読性が向上して保守しやすい状態になったと考えています。

まとめ

「新しいことをやってみたい!」からKotlinにチャレンジしました。
ちょっと注意が必要な点もありましたが、それを上回る多くの恩恵を受けることができました。
また、Kotlin未経験のメンバーだけでも、短い期間で成果を上げることができました。
サーバサイドKotlinに興味のある方は是非お試しください!

登壇してみて

北澤・柏熊の2人とも初めての社外登壇を経験できました。
業務と両立しながらの資料作成だったので大変でしたが、登壇後に参加者の方と情報交換ができたので良かったです!

おわりに

 採用情報をお伝えします。 北澤と柏熊が所属するプラットフォーム事業本部 ペイメントサービス部では、一緒に働く仲間を募集しています。
年間2,110億円超の売上を誇る「DMM.com」の約50%の決済を支える「DMMポイント」プラットフォームを一緒に創造していきましょう!

dmm-corp.com