🦁

kotlin初学者がサーバーサイド開発の検討をしてみた

に公開

概要

今回は、複雑なことをしない簡易的な個人開発を考えるとします。
概要設計として、以下の処理を基本線とします。
その中で、kotlinをサーバーサイドに組み込んだら、どのような考えになるかをjavaで考えたときと比較してみたいと思います。

目的

自分が考える最強のアーキテクチャはこれだ!という話ではなく、あくまでkotlinを使用したらどんな感じになるかをイメージさせるための記事です。

シーケンス図

それぞれの構成

画面はフロントなので割愛します。
Serviceについてはjavaとkotlinで大きく異なるということはないので割愛します。

Controller kotlin

Controllerはmain関数とします。
main関数にHttpServerを追加すれば軽量サーバーとルーティング定義が設定できます。
プログラムにサーバーを内蔵させる形ですね。

fun main {
    val server = HttpServer.create(InetSocketAddress(8080), 0)
    server.createContext("/api/hello") { exchange ->
        // TODO Serviceクラス呼び出し
        val response = "レスポンス返却"
        exchange.sendResponseHeaders(200, response.toByteArray().size.toLong())
        exchange.responseBody.use { it.write(response.toByteArray()) }
    }
}

Controller kotinに対してJava

これがjavaになると、メソッドだけではなく、HttpServetを継承しないといけないので、kotlinのほうがわかりやすそうですね。
サーバーを組み込むとなるとさらに、mainメソッドが必要になるので大変ですね・・・・

public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        String response = "レスポンス返却"; // TODO Serviceクラス呼び出し
        resp.setContentType("text/plain; charset=UTF-8");
        resp.setStatus(HttpServletResponse.SC_OK);

        try (PrintWriter out = resp.getWriter()) {
            out.write(response);
        }
    }
}

Database kotlin

kotlinではExposedを使用して考えてみます。
テーブル定義はユーザで「id」「name」だけにしときます。
テーブル定義もコードだけで読み取れて、transactionもブロック単位で書けるのが良いですね。

object Users : Table("users") {
    val id = integer("id").autoIncrement()
    val name = varchar("name", length = 50)
    override val primaryKey = PrimaryKey(id)
}

fun main() {
    // メモリ保存
    Database.connect(
        "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;",
        "org.h2.Driver"
    )

    transaction {
        // テーブルの作成
        create(Users)

        // データの挿入
        Users.insert {
            it[name] = "イッシー"
        }
    }
}

Database kotinに対してJava

javaの場合はSpringJPAで考えてみます。
「エンティティクラス」「リポジトリインターフェイス」「設定クラス」の3つは用意しないといけないのと、「エンティティクラス」についてはsetter getterも用意しないといけないので大変ですね・・・
kotlinがいかにシンプルかがわかります。
「リポジトリ」に関してはインターフェイスなので、使用方法も一苦労です。
今回の例では、コード上でリポジトリを使用できるように設定

// エンティティ(テーブル定義)
@Entity
@Table(name = "users")
class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    // getter/setter
    public Long getId() { return id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
}

// リポジトリ
@Repository
interface UserRepository extends JpaRepository<User, Long> {}

// 設定クラス
@Configuration
@EnableAutoConfiguration
@ComponentScan
class AppConfig {}

public class MainApp {
    public static void main(String[] args) {
        try (AnnotationConfigApplicationContext context =
                     new AnnotationConfigApplicationContext(AppConfig.class)) {
            UserRepository repo = context.getBean(UserRepository.class);

            // Insert
            User user = new User();
            alice.setName("イッシー");
            repo.save(alice);
        }
    }
}

比較してみて思ったこと

kotlinは簡略的に自由に書ける印象を持ったのに対して、javaのほうは制約がしっかりしていて、決まった感じで作れる印象を持ちました。
決まりがあって、しっかり作りたい場合はjavaで、自由に簡略的に作りたい場合はkotlinを採用すればよいかなと思いました。
学習コストは上記内容からkotlinのほうが圧倒的に少ないかなと思いました。

Discussion