やってみよう、サーバーサイド Kotlin

和田です。趣味は Rising Storm2: Vietnam でやる芋砂です。

さて、先日開催された Google I/O 2017 では、 JetBrains 社が開発している JVM 言語 Kotlin がめでたく Android の公式開発言語になりました!

これで名実ともに Android 言語となったわけですが、 Kotlin は別に Android 専用じゃなくてもいいじゃない。そうです。JVM 言語なのだからサーバーサイドも Kotlin で行こうじゃない!

というわけで Kotlin でかける Web Application Framework をざっくり紹介です。

確認環境

  • macOS 10.12.5
  • Java 1.8.0
  • Kotlin 1.1.2
  • Maven 3.3.9
  • IntelliJ IDEA 2017.1

Spring Framework

トップバッターは最近の Java の WAF といったらこれ、というぐらいな Spring Framework です。そうなのです、ついに次期バージョンの 5 から Kotlin に対応するのです!

本記事を書いている 2017/5/29 現在は、 RC1 がリリースされている状態ですが、近い将来、使えるようになりそうです。なお筆者は Spring Framework をほとんど触ったことがありません :p

以下、コードです。

<parent>  
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.0.BUILD-SNAPSHOT</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>  
    <kotlin.compiler.incremental>true</kotlin.compiler.incremental>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <kotlin.version>1.1.2</kotlin.version>
</properties>

<dependencies>  
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.jetbrains.kotlin</groupId>
        <artifactId>kotlin-stdlib-jre8</artifactId>
        <version>${kotlin.version}</version>
    </dependency>
    <dependency>
        <groupId>org.jetbrains.kotlin</groupId>
        <artifactId>kotlin-reflect</artifactId>
        <version>${kotlin.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>  
    <sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
    <testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
        <plugin>
            <artifactId>kotlin-maven-plugin</artifactId>
            <groupId>org.jetbrains.kotlin</groupId>
            <version>${kotlin.version}</version>
            <configuration>
                <compilerPlugins>
                    <plugin>spring</plugin>
                </compilerPlugins>
                <jvmTarget>1.8</jvmTarget>
            </configuration>
            <executions>
                <execution>
                    <id>compile</id>
                    <phase>compile</phase>
                    <goals>
                        <goal>compile</goal>
                    </goals>
                </execution>
                <execution>
                    <id>test-compile</id>
                    <phase>test-compile</phase>
                    <goals>
                        <goal>test-compile</goal>
                    </goals>
                </execution>
            </executions>
            <dependencies>
                <dependency>
                    <groupId>org.jetbrains.kotlin</groupId>
                    <artifactId>kotlin-maven-allopen</artifactId>
                    <version>${kotlin.version}</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>  
package com.example.spring

import org.springframework.boot.SpringApplication  
import org.springframework.boot.autoconfigure.SpringBootApplication  
import org.springframework.web.bind.annotation.RequestMapping  
import org.springframework.web.bind.annotation.RequestMethod  
import org.springframework.web.bind.annotation.RestController

@RestController
@RequestMapping("/hello")
@SpringBootApplication
class DemoApplication {

    @RequestMapping(method = arrayOf(RequestMethod.GET))
    fun hello(): String {
        return "hello, world with Kotlin!"
    }
}

fun main(args: Array<String>) {  
    SpringApplication.run(DemoApplication::class.java, *args)
}

http://localhost:8080/hello へアクセスすると hello, world with Kotlin! という文字列が表示されるはずです。

ktor

JetBrains 社が作っている WAF です。

Spring Framework と比べるとシンプルみがあります。 Single Page Application や API をサクッと作るにはいいかもしれません。

<repositories>  
    <repository>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
        <id>bintray-kotlin-ktor</id>
        <name>bintray</name>
        <url>https://dl.bintray.com/kotlin/ktor</url>
    </repository>
</repositories>

<build>  
    <plugins>
        <plugin>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-maven-plugin</artifactId>
            <version>${kotlin.version}</version>
            <executions>
                <execution>
                    <id>compile</id>
                    <phase>compile</phase>
                    <goals>
                        <goal>compile</goal>
                    </goals>
                </execution>
                <execution>
                    <id>test-compile</id>
                    <phase>test-compile</phase>
                    <goals>
                        <goal>test-compile</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

<dependencies>  
    <dependency>
        <groupId>org.jetbrains.ktor</groupId>
        <artifactId>ktor-core</artifactId>
        <version>${ktor.version}</version>
    </dependency>
    <dependency>
        <groupId>org.jetbrains.ktor</groupId>
        <artifactId>ktor-jetty</artifactId>
        <version>${ktor.version}</version>
    </dependency>
    <dependency>
        <groupId>org.jetbrains.kotlin</groupId>
        <artifactId>kotlin-stdlib-jre8</artifactId>
        <version>${kotlin.version}</version>
    </dependency>
    <dependency>
        <groupId>org.jetbrains.kotlin</groupId>
        <artifactId>kotlin-test</artifactId>
        <version>${kotlin.version}</version>
        <scope>test</scope>
    </dependency>
</dependencies>  
package com.example.ktor

import org.jetbrains.ktor.application.call  
import org.jetbrains.ktor.host.embeddedServer  
import org.jetbrains.ktor.http.ContentType  
import org.jetbrains.ktor.jetty.Jetty  
import org.jetbrains.ktor.response.respondText  
import org.jetbrains.ktor.routing.get  
import org.jetbrains.ktor.routing.routing

fun main(args: Array<String>) {  
    embeddedServer(Jetty, 8080) {
        routing {
            get("/hello") {
                call.respondText("hello, world with Kotlin!", ContentType.Text.Html)
            }
        }
    }.start(wait = true)
}

これも先程の Spring Framework と同じく http://localhost:8080/hello へアクセスすると hello, world with Kotlin! という文字列が表示されるはずです。

Wasabi

こちらは先ほど紹介した Kotlin/ktor にマージされたプロジェクトになりますが、一応紹介。

やはり SPA や API サーバーが向いているのかなと思います。ただ、先述の通り ktor にマージされたため、今更使う意味は無いのかなと思います。

    <dependency>
        <groupId>org.wasabifx</groupId>
        <artifactId>wasabi</artifactId>
        <version>0.3.129</version>
    </dependency>

<repositories>  
    <repository>
        <id>wasabifx</id>
        <name>Wasabi WAF</name>
        <url>https://dl.bintray.com/wasabifx/wasabifx/</url>
    </repository>
</repositories>  
package com.example.wasabi

import org.wasabifx.wasabi.app.AppServer

fun main(args: Array<String>) {  
    val appServer = AppServer()
    appServer.get("/hello", {
        response.send("hello, world with Kotlin!")
    })

    appServer.start()
}

これは http://localhost:3000/hello へアクセスすると hello, world with Kotlin! という文字列が表示されるはずです。


こんな感じでしょうか。

ガッツリサーバーサイドを作り込むなら Spring Framework 、シュッと作るなら ktor と言った感じでしょうか。

わりとスクリプト言語のようにラフにかけて、今までの Java 資産や、型の恩恵にあずかれ、さらに Android までかけちゃう Server Side Kotlin はいかがでしょうか?