GAE/Kotlinをはじめる！

[Kotlin Advent Calendar 2015](http://www.adventar.org/calendars/857)の16日目の記事です。

KotlinはJVMで動くプログラミング言語です。
イマドキの文法とタイプセーフな型システムでさくさく安全に書ける言語です。

そしてGoogle App EngineはGoogle.comと同じインフラでアプリケーションを動かせるGoogleのPaaSでサポートされている言語はPython/Java/PHP/Goです。

どんなサイズのアプリケーションも最初っからスケールを意識して書かなければいけなくてちょっと掴みづらいですが最近は日本語のドキュメントも増えつつあるので初心者にも扱えるようになってきてるのではないかなと思います。

特に料金も無料枠があるので使われなければお金がかからないし
突然大量のアクセスがあってもスケールが容易なので個人開発やスタートアップにはオススメのプラットフォームといえると思います。

# 環境
MacOSX
Google Cloud SDK 1.9.28
Kotlin 1.0.0-beta-2423

# プロジェクト作成

ディレクトリを作成して `gradle init`でプロジェクトを作り

`build.gradle`を編集します。


```groovy:build.gradle
buildscript {
    ext.kotlin_version = '1.0.0-beta-2423'
    ext.gae_sdk_version = '1.9.28'
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.google.appengine:gradle-appengine-plugin:1.9.18'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

repositories {
    jcenter()
}

apply plugin: 'java'
apply plugin: 'kotlin'
apply plugin: 'war'
apply plugin: 'appengine'

sourceCompatibility = JavaVersion.VERSION_1_7
targetCompatibility = JavaVersion.VERSION_1_7

dependencies {
    appengineSdk "com.google.appengine:appengine-java-sdk:$gae_sdk_version"

    compile 'javax.servlet:servlet-api:2.5'
    compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    compile "com.google.appengine:appengine-api-labs:$gae_sdk_version"
    compile 'net.sf.jsr107cache:jsr107cache:1.1'
    compile "com.google.appengine:appengine-jsr107cache:$gae_sdk_version"

    testCompile "com.google.appengine:appengine-api-stubs:$gae_sdk_version"
    testCompile "com.google.appengine:appengine-testing:$gae_sdk_version"
}

appengine {
    downloadSdk = true
    appcfg {
        oauth2 = true
    }
}

task layout << {
    sourceSets*.allSource.srcDirs*.each { it.mkdirs() }
    new File(sourceSets.main.resources.srcDirs[0], 'META-INF').mkdirs()
    new File(webAppDir, 'WEB-INF').mkdirs()
}
```

`./gradlew layout`でsrcディレクトリなども作成できます。
IntelliJなどでプロジェクトを読み込んでおくと作業が楽になります。

# Hello GAE/Kotlin

[公式ドキュメント](https://cloud.google.com/appengine/docs/java/)のコードをKotlinにしただけなのでコードは面白みありませんが一応

`src/main/kotlin`にパッケージを作成します。
今回は`com.inukoya.example`で作成しました。

その直下に`MyServlet.kt`を作成します。

```kotlin
class MyServlet : HttpServlet() {

    public override fun doGet(req: HttpServletRequest, res: HttpServletResponse) {
        res.contentType = "text/plain"
        res.writer.println("Please use the form to POST to this url")
    }

    public override fun doPost(req: HttpServletRequest, res: HttpServletResponse) {
        val name = req.getParameter("name")
        res.contentType = "text/plain"
        if (name == null) {
            res.writer.println("Please enter a name")
        }
        res.writer.println("Hello $name")
    }
}
```

次に`src/main/webapp/WEB-INF/`に`appengine-web-app.xml`を作成します。

applicationにはapplicationIdを入れるのですが今回はローカルで動かすだけなので入れなくても大丈夫です。

```xml:appengine-web-app.xml
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
    <application></application>
    <version>1</version>
    <threadsafe>true</threadsafe>
</appengine-web-app>
```

次にルーティングをします。appengine-web-app.xmlと同じディレクトリに`web.xml`を作成します。

```xml:web.xml
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
    <servlet>
        <servlet-name>MyServlet</servlet-name>
        <servlet-class>com.inukoya.example.MyServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>MyServlet</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
</web-app>
```

welcome-file-listのindex.htmlは`src/main/webapp/`に作成しておきます。

ここまでできたら後は以下のコマンドでdevサーバーを起動できます。

```base
$ ./gradlew appengineRun
```

http://localhost:8080 にアクセスできればOKです。

![スクリーンショット 2015-12-13 16.37.08.png](https://qiita-image-store.s3.amazonaws.com/0/15818/8f7e0061-8809-2c96-1662-5083831a0aac.png)

![スクリーンショット 2015-12-13 16.37.12.png](https://qiita-image-store.s3.amazonaws.com/0/15818/13fed415-ceb5-97ad-b434-f64c863cc12d.png)

コードはGitHubにあげています https://github.com/k2wanko/gae-kotlin-example

# まとめ

思いつきでやってみましたが悪くはない気はします
でも、別に今のところはただのJavaの置き換えでしかないので
無理に使う必要性もない気はします。

KotlinのWebFrameworkもまだまだ発展途上なのでKotlinらしさを活かした
GAEで動くFrameworkが登場するのを待つか作るかをする必要がありそうでした。

# 参考

http://qiita.com/kumazo@github/items/7eeb83926a4265fb8d39