Upgrade to Pro — share decks privately, control downloads, hide ads and more …

DMM.comの課金プラットフォームにおけるサーバーサイドKotlin事情

 DMM.comの課金プラットフォームにおけるサーバーサイドKotlin事情

現在、DMM.comは40を超えるサービスを展開しております。
私たち課金プラットフォームは、様々なサービスで利用できる決済手段などを提供しています。
課金プラットフォームには元々Javaエンジニアが多く在籍していますが、最近はプロダクトにKotlinを積極的に採用しています。
本セッションでは、なぜKotlinを採用したのか?また、実際に複数プロダクトで採用した経験からJavaと比較したメリット・デメリットについてご紹介します。
プロダクトにKotlinを採用するための、判断材料となる情報を提供できればと思います。

https://event.shoeisha.jp/devboost/20181215/session/1894/

kashiwaguma-hiro

December 15, 2018
Tweet

More Decks by kashiwaguma-hiro

Other Decks in Technology

Transcript

  1. © DMM.com
    DMM.comの
    課金プラットフォームにおける
    サーバサイドKotlin事情
    DMM.com 北澤由貴 / 柏熊宏幸
    2018/12/15
    #devboostB 【B-2】

    View Slide

  2. © DMM.com
    自己紹介
    北澤 由貴(Kitazawa Yoshitaka)
    合同会社DMM.com
    ペイメントサービス部
    2
    柏熊 宏幸(Kashiwaguma Hiroyuki)
    合同会社DMM.com
    ペイメントサービス部

    View Slide

  3. © DMM.com
    アジェンダ
    • DMM.comについてのご紹介
    • DMM.comの課金プラットフォームでKotlinを採用した理由
    • 使っていく中で気づいた良い点・使いにくい点
    • 課金プラットフォームのKotlin利用実績
    • まとめ
    3

    View Slide

  4. © DMM.com
    DMM.comについての
    ご紹介
    4

    View Slide

  5. © DMM.com
    DMM.comについて
    40以上のサービスを展開するサービスサイト
    5

    View Slide

  6. © DMM.com
    DMM.comについて
    6
    ※DMM.com、DMM GAMES、DMM.com 証券、DMM.com OVERRIDE、DMM.com Base、他連結 ※DMM.com サービスの会員数

    View Slide

  7. © DMM.com
    DMM.comの課金プラットフォームについて
    7

    View Slide

  8. © DMM.com
    DMM.comの課金プラットフォームについて
    8
    APIにKotlin
    つかってるで!

    View Slide

  9. © DMM.com
    DMM.comの
    課金プラットフォームで
    Kotlinを採用した理由
    9

    View Slide

  10. © DMM.com
    • 新しいことがやってみたい!
    • 理あにかなってさえいれば技術選定は自由
    • Javaの資産を再利用、コード量の削減も見込める
    • 今後長く使える言語
    • Android公式言語に採用された
    • 企業(JetBrains社)でメンテナンスされている
    • 開発終了し、メンテナンスされなくなる可能性は低い
    • Javaエンジニアにとって習得が容易
    • 過半数がJavaエンジニア
    • Javaとの互換性がある、IDEでJava→Kotlin変換
    なぜKotlinを採用したのか
    10

    View Slide

  11. © DMM.com
    • 新しいことがやってみたい!
    • 理にかなってさえいれば技術選定は自由
    • Javaの資産を再利用、コード量の削減も見込める
    • 今後長く使える言語
    • Android公式言語に採用された
    • 企業(JetBrains社)でメンテナンスされている
    • 開発終了し、メンテナンスされなくなる可能性は低い
    • Javaエンジニアにとって習得が容易
    • 過半数がJavaエンジニア
    • Javaとの互換性がある、IDEでJava→Kotlin変換
    なぜKotlinを採用したのか
    11

    View Slide

  12. © DMM.com
    • 新しいことがやってみたい!
    • 理にかなってさえいれば技術選定は自由
    • Javaの資産を再利用、コード量の削減も見込める
    • 今後長く使える言語
    • Android公式言語に採用された
    • JetBrains社でメンテナンスされている
    • 開発終了し、メンテナンスされなくなる可能性は低い
    • Javaエンジニアにとって習得が容易
    • 過半数がJavaエンジニア
    • Javaとの互換性がある、IDEでJava→Kotlin変換
    なぜKotlinを採用したのか
    12

    View Slide

  13. © DMM.com
    • 新しいことがやってみたい!
    • 理にかなってさえいれば技術選定は自由
    • Javaの資産を再利用、コード量の削減も見込める
    • 今後長く使える言語
    • Android公式言語に採用された
    • JetBrains社でメンテナンスされている
    • 開発終了し、メンテナンスされなくなる可能性は低い
    • Javaエンジニアにとって習得が容易
    • 過半数がJavaエンジニア
    • Javaとの互換性があり、IDEでのJava→Kotlin変換も可能
    なぜKotlinを採用したのか
    13

    View Slide

  14. © DMM.com
    使っていく中で気づいた
    良い点・使いにくい点
    14

    View Slide

  15. © DMM.com
    Javaと比べて
    ちょっと便利なところ3つ
    15

    View Slide

  16. © DMM.com
    ①DataClass
    16
    public class User {
    private String name;
    private int age;
    public void setName(String name) {
    this.name = name;
    }
    ~~~ 略 ~~~
    @Override public boolean equals(Object o) {
    ~~~ 略 ~~~
    @Override public String toString() {
    return "User{name='"+name+'\''+",age="+age
    +'}';
    }
    }
    data class User(var name: String, var age: Int)
    Kotlin
    Java
    • データ格納クラスを、簡単かつコード量少なく実装できる

    View Slide

  17. © DMM.com
    ①DataClass
    • データ格納クラスを、簡単かつコード量少なく実装できる
    17
    public class User {
    private String name;
    private int age;
    public void setName(String name) {
    this.name = name;
    }
    ~~~ 略 ~~~
    @Override public boolean equals(Object o) {
    ~~~ 略 ~~~
    @Override public String toString() {
    return "User{name='"+name+'\''+",age="+age
    +'}';
    }
    }
    data class User(var name: String, var age: Int)
    Kotlin
    Java
    getter/ setter
    equalsなど実装が必要

    View Slide

  18. © DMM.com
    ①DataClass
    • データ格納クラスを、簡単かつコード量少なく実装できる
    18
    public class User {
    private String name;
    private int age;
    public void setName(String name) {
    this.name = name;
    }
    ~~~ 略 ~~~
    @Override public boolean equals(Object o) {
    ~~~ 略 ~~~
    @Override public String toString() {
    return "User{name='"+name+'\''+",age="+age
    +'}';
    }
    }
    data class User(var name: String, var age: Int)
    Kotlin
    Java
    getter/ setter
    equalsなど実装が必要
    dataクラスにすることで
    同じ効果!

    View Slide

  19. © DMM.com
    ①DataClass
    • データ格納クラスを、簡単かつコード量少なく実装できる
    19
    public class User {
    private String name;
    private int age;
    public void setName(String name) {
    this.name = name;
    }
    ~~~ 略 ~~~
    @Override public boolean equals(Object o) {
    ~~~ 略 ~~~
    @Override public String toString() {
    return "User{name='"+name+'\''+",age="+age
    +'}';
    }
    }
    data class User(var name: String, var age: Int)
    Kotlin
    Java
    getter/ setter
    equalsなど実装が必要
    dataクラスにすることで
    同じ効果!
    Java : 51行
        ↓
    Kotlin: 1行!

    View Slide

  20. © DMM.com
    ②raw string
    • コード上でSQLやJSONを表記したいとき、見やすく表現できる
    20
    @Query("SELECT"
    + " * "
    + "FROM"
    + " history_detail"
    + "WHERE"
    + "transaction_id = :transaction_id"
    + "AND valid_flag = 1",
    nativeQuery = true)
    public List
    findByTransactionId(@Param("transaction_id")
    String transactionId);
    @Query("""
    SELECT
    *
    FROM
    history_detail
    WHERE
    transaction_id = :transaction_id
    AND valid_flag = 1
    """,
    nativeQuery = true)
    fun findByTransactionId(@Param("transaction_id")
    transactionId: String): List
    Kotlin
    Java

    View Slide

  21. © DMM.com
    ②raw string
    • コード上でSQLやJSONを表記したいとき、見やすく表現できる
    21
    @Query("SELECT"
    + " * "
    + "FROM"
    + " history_detail"
    + "WHERE"
    + "transaction_id = :transaction_id"
    + "AND valid_flag = 1",
    nativeQuery = true)
    public List
    findByTransactionId(@Param("transaction_id")
    String transactionId);
    @Query("""
    SELECT
    *
    FROM
    history_detail
    WHERE
    transaction_id = :transaction_id
    AND valid_flag = 1
    """,
    nativeQuery = true)
    fun findByTransactionId(@Param("transaction_id")
    transactionId: String): List
    Kotlin
    Java
    Javaは改行すると見づらい
    Kotlinはraw stringで改行表現できる

    View Slide

  22. © DMM.com
    ②raw string
    • コード上でSQLやJSONを表記したいとき、見やすく表現できる
    22
    @Query("SELECT"
    + " * "
    + "FROM"
    + " history_detail"
    + "WHERE"
    + "transaction_id = :transaction_id"
    + "AND valid_flag = 1",
    nativeQuery = true)
    public List
    findByTransactionId(@Param("transaction_id")
    String transactionId);
    @Query("""
    SELECT
    *
    FROM
    history_detail
    WHERE
    transaction_id = :transaction_id
    AND valid_flag = 1
    """,
    nativeQuery = true)
    fun findByTransactionId(@Param("transaction_id")
    transactionId: String): List
    Kotlin
    Java
    実はスペース開け忘れ!
    実行時エラー!
    Javaは改行すると見づらい
    Kotlinはraw stringで改行表現できる

    View Slide

  23. © DMM.com
    ③null safety
    • NullPointerExceptionを、コンパイル時に防げる!
    23
    Kotlin
    var str :String = nullReturnMethod()
    print( str.toLowerCase() )
    Java
    String str = nullReturnMethod();
    System.out.print( str.toLowerCase() );

    View Slide

  24. © DMM.com
    ③null safety
    • NullPointerExceptionを、コンパイル時に防げる!
    24
    Kotlin
    Javaは実行時エラー!(NullPointerException)
    Kotlinはコンパイル時エラー!(変数代入時に)
    var str :String = nullReturnMethod()
    print( str.toLowerCase() )
    Java
    String str = nullReturnMethod();
    System.out.print( str.toLowerCase() );

    View Slide

  25. © DMM.com
    ③null safety
    • NullPointerExceptionを、コンパイル時に防げる!
    25
    Kotlin
    var str :String? = nullReturnMethod()
    print( str.toLowerCase() )
    nullが入る可能性がある場合、変数に「?」を付与
    Java
    String str = nullReturnMethod();
    System.out.print( str.toLowerCase() );

    View Slide

  26. © DMM.com
    ③null safety
    • NullPointerExceptionを、コンパイル時に防げる!
    26
    Kotlin
    var str :String? = nullReturnMethod()
    print( str.toLowerCase() )
    Java
    String str = nullReturnMethod();
    System.out.print( str.toLowerCase() );
    すると、変数参照時にコンパイルエラーに変わる

    View Slide

  27. © DMM.com
    ③null safety
    • NullPointerExceptionを、コンパイル時に防げる!
    27
    Kotlin
    var str :String? = nullReturnMethod()
    print( str?.toLowerCase() )
    Java
    String str = nullReturnMethod();
    System.out.print( str.toLowerCase() );
    コンパイルエラーを解消するには、
    safe call演算子を使う(null以外のみ関数実行)

    View Slide

  28. © DMM.com
    ③null safety
    • NullPointerExceptionを、コンパイル時に防げる!
    28
    Kotlin
    var str :String? = nullReturnMethod()
    print( str?.toLowerCase() ?: "default" )
    Java
    String str = nullReturnMethod();
    System.out.print( str.toLowerCase() );
    また、エルビス演算子を使うことで、
    nullの場合のデフォルト値を指定可能

    View Slide

  29. © DMM.com
    • NullPointerExceptionを、コンパイル時に防げる!
    var str :String? = nullReturnMethod()
    print( str?.toLowerCase() ?: "default" )
    ③null safety
    29
    Kotlin
    ちなみに、Javaでも同じようなコードを実現できるが
    コード量が多くつらい...
    Java
    Optional str =
    Optional.ofNullable(nullReturnMethod());
    str.ifPresentOrElse(
    s->System.out.print( str.toLowerCase() ),
    ()->System.out.print("default")
    );

    View Slide

  30. © DMM.com
    • コードが簡潔に、短く書ける!
    • コードの表現力が上がった!
    • Null safetyで、早い段階からバグを防げる!
    ちょっと便利なところ3つのまとめ
    30

    View Slide

  31. © DMM.com
    Javaと比べて
    ラムダ式が扱いやすい
    31

    View Slide

  32. © DMM.com 32
    そもそもラムダ式とは?
    • 無名関数の記述方法のひとつ
    • Java8からラムダ式で簡潔に書ける
    public class Main {
    public static void main(String[] args) {
    Runnable r = new Runnable(){
    @Override
    public void run() {
    System.out.println("Hello world.");
    }
    };
    r.run();
    }
    }
    public class Main {
    public static void main(String[] args) {
    Runnable r = () -> {
    System.out.println("Hello world.");
    };
    r.run();
    }
    }
    Java 無名関数 Java ラムダ式

    View Slide

  33. © DMM.com 33
    そもそもラムダ式とは?
    • 無名関数の記述方法のひとつ
    • Java8からラムダ式で簡潔に書ける
    public class Main {
    public static void main(String[] args) {
    Runnable r = new Runnable(){
    @Override
    public void run() {
    System.out.println("Hello world.");
    }
    };
    r.run();
    }
    }
    public class Main {
    public static void main(String[] args) {
    Runnable r = () -> {
    System.out.println("Hello world.");
    };
    r.run();
    }
    }
    Java 無名関数 Java ラムダ式
    無名関数だと本質的でない
    コードが多い

    View Slide

  34. © DMM.com 34
    そもそもラムダ式とは?
    • 無名関数の記述方法のひとつ
    • Java8からラムダ式で簡潔に書ける
    public class Main {
    public static void main(String[] args) {
    Runnable r = new Runnable(){
    @Override
    public void run() {
    System.out.println("Hello world.");
    }
    };
    r.run();
    }
    }
    public class Main {
    public static void main(String[] args) {
    Runnable r = () -> {
    System.out.println("Hello world.");
    };
    r.run();
    }
    }
    Java 無名関数 Java ラムダ式
    newとrun()のオーバライドを省略
    無名関数だと本質的でない
    コードが多い

    View Slide

  35. © DMM.com 35
    ラムダ式をつかった例を比較
    public class Main {
    public static void main(String[] args) {
    Runnable r = () -> {
    System.out.println("Hello world.");
    };
    r.run();
    }
    }
    public class Main {
    fun main(args: Array) {
    val r = { print("Hello world.") }
    r()
    }
    }
    • Kotlinでもラムダ式を利用できる
    • JavaもKotlinも、この状態だと大差ない
    Kotlin
    Java

    View Slide

  36. © DMM.com 36
    例1. Intを2つ受け取って演算
    • JavaではBiFunctionという関数型インタフェースを使用
    public class Main {
    fun main(args: Array) {
    val op = { a:Int, b:Int -> a+b}
    calc(1,2,op) // 3
    }
    fun calc(a: Int, b: Int,
    op: (Int, Int) -> Int): Int {
    return op(a, b)
    }
    }
    public class Main {
    public static void main(String[] args) {
    BiFunction op
    = (a, b) -> a+b;
    calc(1, 2, op); // 3
    }
    public static Integer calc(Integer a, Integer b,
         BiFunction op){
    return op.apply(a,b);
    }
    }
    Kotlin
    Java

    View Slide

  37. © DMM.com 37
    例1. Intを2つ受け取って演算
    • JavaではBiFunctionという関数型インタフェースを使用
    public class Main {
    fun main(args: Array) {
    val op = { a:Int, b:Int -> a+b}
    calc(1,2,op) // 3
    }
    fun calc(a: Int, b: Int,
    op: (Int, Int) -> Int): Int {
    return op(a, b)
    }
    }
    public class Main {
    public static void main(String[] args) {
    BiFunction op
    = (a, b) -> a+b;
    calc(1, 2, op); // 3
    }
    public static Integer calc(Integer a, Integer b,
         BiFunction op){
    return op.apply(a,b);
    }
    }
    Kotlin
    Java Integerを2つ受け取って
    足し算結果を返す

    View Slide

  38. © DMM.com 38
    例1. Intを2つ受け取って演算
    • JavaではBiFunctionという関数型インタフェースを使用
    public class Main {
    fun main(args: Array) {
    val op = { a:Int, b:Int -> a+b}
    calc(1,2,op) // 3
    }
    fun calc(a: Int, b: Int,
    op: (Int, Int) -> Int): Int {
    return op(a, b)
    }
    }
    public class Main {
    public static void main(String[] args) {
    BiFunction op
    = (a, b) -> a+b;
    calc(1, 2, op); // 3
    }
    public static Integer calc(Integer a, Integer b,
         BiFunction op){
    return op.apply(a,b);
    }
    }
    Kotlin
    Java 型名はBiFunction
    Integerを2つ受け取って
    足し算結果を返す

    View Slide

  39. © DMM.com
    • JavaではBiFunctionという関数型インタフェースを使用
    39
    例1. Intを2つ受け取って演算
    public class Main {
    fun main(args: Array) {
    val op = { a:Int, b:Int -> a+b}
    calc(1,2,op) // 3
    }
    fun calc(a: Int, b: Int,
    op: (Int, Int) -> Int): Int {
    return op(a, b)
    }
    }
    public class Main {
    public static void main(String[] args) {
    BiFunction op
    = (a, b) -> a+b;
    calc(1, 2, op); // 3
    }
    public static Integer calc(Integer a, Integer b,
         BiFunction op){
    return op.apply(a,b);
    }
    }
    Kotlin
    Java 型名はBiFunction
    Integerを2つ受け取って
    足し算結果を返す
    リファレンスが必要
    覚えるのはツライ

    View Slide

  40. © DMM.com
    • JavaではBiFunctionという関数型インタフェースを使用
    40
    例1. Intを2つ受け取って演算
    public class Main {
    fun main(args: Array) {
    val op = { a:Int, b:Int -> a+b}
    calc(1,2,op) // 3
    }
    fun calc(a: Int, b: Int,
    op: (Int, Int) -> Int): Int {
    return op(a, b)
    }
    }
    public class Main {
    public static void main(String[] args) {
    BiFunction op
    = (a, b) -> a+b;
    calc(1, 2, op); // 3
    }
    public static Integer calc(Integer a, Integer b,
         BiFunction op){
    return op.apply(a,b);
    }
    }
    Kotlin
    Java 型名はBiFunction
    Integerを2つ受け取って
    足し算結果を返す
    リファレンスが必要
    覚えるのはツライ
    Kotlinは関数自体が
    オブジェクト

    View Slide

  41. © DMM.com
    • JavaではBiFunctionという関数型インタフェースを使用
    41
    例1. Intを2つ受け取って演算
    public class Main {
    fun main(args: Array) {
    val op = { a:Int, b:Int -> a+b}
    calc(1,2,op) // 3
    }
    fun calc(a: Int, b: Int,
    op: (Int, Int) -> Int): Int {
    return op(a, b)
    }
    }
    public class Main {
    public static void main(String[] args) {
    BiFunction op
    = (a, b) -> a+b;
    calc(1, 2, op); // 3
    }
    public static Integer calc(Integer a, Integer b,
         BiFunction op){
    return op.apply(a,b);
    }
    }
    Kotlin
    Java 型名はBiFunction
    Integerを2つ受け取って
    足し算結果を返す
    リファレンスが必要
    覚えるのはツライ
    定義したラムダ式の型
    を指定
    Kotlinは関数自体が
    オブジェクト

    View Slide

  42. © DMM.com 42
    例2. Intを3つ受け取って演算
    fun main(args: Array) {
    val op = {a:Int,b:Int,c:Int -> a+b+c}
    calc(1,2,3,op) // 6
    }
    fun calc(a: Int, b: Int, c: Int,
    op: (Int, Int, Int) -> Int): Int {
    return op(a, b, c)
    }
    public static void main(String[] args) {
    TriFunction op
    = (a, b, c) -> a+b+c;
    calc(1, 2, 3, op); //6
    }
    public static Integer calc(Integer a,Integer b,Integer c,
      TriFunction op){
    return op.apply(a,b,c);
    }
    @FunctionalInterface interface TriFunction{
    R apply(A a, B b, C c);
    }
    • Javaでは3つ受け取る関数型インタフェース定義が必要
    Kotlin
    Java

    View Slide

  43. © DMM.com 43
    例2. Intを3つ受け取って演算
    fun main(args: Array) {
    val op = {a:Int,b:Int,c:Int -> a+b+c}
    calc(1,2,3,op) // 6
    }
    fun calc(a: Int, b: Int, c: Int,
    op: (Int, Int, Int) -> Int): Int {
    return op(a, b, c)
    }
    public static void main(String[] args) {
    TriFunction op
    = (a, b, c) -> a+b+c;
    calc(1, 2, 3, op); //6
    }
    public static Integer calc(Integer a,Integer b,Integer c,
      TriFunction op){
    return op.apply(a,b,c);
    }
    @FunctionalInterface interface TriFunction{
    R apply(A a, B b, C c);
    }
    • Javaでは3つ受け取る関数型インタフェース定義が必要
    Kotlin
    Java
    TriFunctionを自作

    View Slide

  44. © DMM.com 44
    例2. Intを3つ受け取って演算
    fun main(args: Array) {
    val op = {a:Int,b:Int,c:Int -> a+b+c}
    calc(1,2,3,op) // 6
    }
    fun calc(a: Int, b: Int, c: Int,
    op: (Int, Int, Int) -> Int): Int {
    return op(a, b, c)
    }
    public static void main(String[] args) {
    TriFunction op
    = (a, b, c) -> a+b+c;
    calc(1, 2, 3, op); //6
    }
    public static Integer calc(Integer a,Integer b,Integer c,
      TriFunction op){
    return op.apply(a,b,c);
    }
    @FunctionalInterface interface TriFunction{
    R apply(A a, B b, C c);
    }
    • Javaでは3つ受け取る関数型インタフェース定義が必要
    Kotlin
    Java
    TriFunctionを自作
    定義したラムダ式の型
    を指定
    Kotlinは関数自体が
    オブジェクト

    View Slide

  45. © DMM.com
    改めてまとめると
    • Java
    • 関数型インタフェースを使用する必要がある
    • 用意されていない場合は自身で関数型インタフェースの定義が必要
    • Kotlin
    • 言語として、第一級関数をサポート
    • 関数自体をオブジェクトとして扱うことが可能
    • 関数を定義する際にインタフェース/クラス定義は不要
    45

    View Slide

  46. © DMM.com
    Javaとの互換性で
    使いにくい点
    46

    View Slide

  47. © DMM.com
    Nullを扱うライブラリと相性が良くない
    • テストコードでMockitoを利用して一部の挙動をMock化したい
    • Mockito.any()はnullをreturnする
    • Kotlinではnullを許容していない場合例外になる
    47
    class HistoryServiceTest {
    @Mock lateinit var historyRepository: HistoryRepository
    @Test fun searchTest() {
    Mockito.doReturn(History("T001", ~))
    .`when`(historyRepository).findByTransactionId(Mockito.any())
    }
    }
    Kotlin java.lang.IllegalStateException:
    Mockito.any() must not be null

    View Slide

  48. © DMM.com
    Nullを扱うライブラリと相性が良くない
    48
    Kotlin
    • テストコードでMockitoを利用して一部の挙動をMock化したい
    • Mockito.any()はnullをreturnする
    • Kotlinではnullを許容していない場合例外になる
    class HistoryServiceTest {
    @Mock lateinit var historyRepository: HistoryRepository
    @Test fun searchTest() {
    Mockito.doReturn(History("T001", ~))
    .`when`(historyRepository).findByTransactionId(com.nhaarman.mockito_kotlin.any())
    }
    }
    nullを考慮したライブラリで
    回避可能

    View Slide

  49. © DMM.com
    課金プラットフォームの
    Kotlin利用実績
    49

    View Slide

  50. © DMM.com
    課金プラットフォームの言語比率
    50
    ※ 課金プラットフォームの24プロダクトの集計結果
    Python : 4%
    PHP : 58%
    Java : 25%
    Kotlin : 13%

    View Slide

  51. © DMM.com
    課金プラットフォームの言語比率
    51
    PHP : 58%
    Java : 25%
    DMMポイントを操作する
    APIの例をご紹介
    Python : 4%
    ※ 課金プラットフォームの24プロダクトの集計結果
    Kotlin : 13%

    View Slide

  52. © DMM.com
    DMMポイントとは
    52
    • DMMで1ポイント1円で利用できるポイントサービス
    • DMMの利用でポイントプレゼント
    • プリペイドカードなどでポイントチャージ可能

    View Slide

  53. © DMM.com
    売上70億円
    500万リクエスト
    DMMポイントとは
    月間で...
    53

    View Slide

  54. © DMM.com
    ポイントAPIをリプレイス
    • DMMポイントの発行や消費をするAPIをリプレイス
    • 一般的でない技術を使用していて可読性が悪い
    • レガシーなミドルウェアを撤去したい
    54

    View Slide

  55. © DMM.com
    ポイントAPIをリプレイス
    • DMMポイントの発行や消費をするAPIをリプレイス
    • 一般的でない技術を使用していて可読性が悪い
    • レガシーなミドルウェアを撤去したい
    55
    リードタイムが長い

    View Slide

  56. © DMM.com
    • DMMポイントの発行や消費をするAPIをリプレイス
    • 一般的でない技術を使用していて可読性が悪い
    • レガシーなミドルウェアを撤去したい
    • アーキテクチャ
    • Kotlin 1.2
    • Spring Framework 5.0
    • Spring Boot 2.0
    • MySQL
    リードタイムが長い
    ポイントAPIをリプレイス
    56

    View Slide

  57. © DMM.com
    ポイントAPIリプレイスの実績
    • 全部で11種類のAPIを作成
    • 開発メンバーは4名
    • ビジネスロジックの開発期間は2ヶ月
    57

    View Slide

  58. © DMM.com
    ポイントAPIリプレイスの実績
    • 全部で11種類のAPIを作成
    • 開発メンバーは4名
    • ビジネスロジックの開発期間は2ヶ月
    58
    全員Kotlin未経験
    Javaができるエンジニア

    View Slide

  59. © DMM.com
    ポイントAPIリプレイスの実績
    • 全部で11種類のAPIを作成
    • 開発メンバーは4名
    • ビジネスロジックの開発期間は2ヶ月
    59
    全員Kotlin未経験
    Javaができるエンジニア
    Kotlinの学習コストが低いので
    短い期間で成果が出せる

    View Slide

  60. © DMM.com
    リプレイス前後のコード量の比較
    60
    コード量
    31%削減
    ※ ビジネスロジックの集計結果
    Java Kotlin

    View Slide

  61. © DMM.com
    実績のまとめ
    61
    • コード量が減って可読性UP
    • レガシーなミドルウェアを撤去
    • Kotlinは学習コストが低いので短期間で成果を出せる

    View Slide

  62. © DMM.com
    実績のまとめ
    62
    • コード量が減って可読性UP
    • レガシーなミドルウェアを撤去
    • Kotlinは学習コストが低いので短期間で成果を出せる
    リードタイムの短縮!

    View Slide

  63. © DMM.com
    実績のまとめ
    63
    • コード量が減って可読性UP
    • レガシーなミドルウェアを撤去
    • Kotlinは学習コストが低いので短期間で成果を出せる
    サーバサイドKotlinは月間70億円を売り上げる
    DMM.comの大規模課金プラットフォームを支えている!
    リードタイムの短縮!

    View Slide

  64. © DMM.com
    まとめ
    64

    View Slide

  65. © DMM.com
    まとめ
    • 「新しいことをやってみたい!」からKotlinにチャレンジ
    • ちょっと注意も必要だが多くの恩恵を受けられた
    • Kotlin未経験のメンバーだけで
    大規模な課金プラットフォームのリプレイスに成功
    65

    View Slide

  66. © DMM.com 66
    Join Our Team!
    DMMグループでは一緒に働く仲間を募集しています。
    https://dmm-corp.com/recruit/engineer
    Serverside Engineer
    Server Engineer
    iOS / Android Engineer
    Frontend Engineer
    Technical Consultant
    UI Designer

    View Slide

  67. © DMM.com
    Thank you for your kind attention!

    View Slide