KotlinをGoogle App Engineで動かしてみる

この投稿は[Kotlin Advent Calendar](http://qiita.com/advent-calendar/2016/kotlin)の14日目の投稿です。

## はじめに

いつもはKotlinでAndroidアプリを作っているのですが、最近Kotlinでサーバサイドの開発をしてみようと思い環境を整えました。そこで同じようにこれからKotlinでサーバサイドの開発をしたいと思っている方の少しでもお役に立てればと思い、Google App EngineでKotlinを動かすまでの環境の作り方を書くことにしました。

エディタにはIntelliJ IDEA、フレームワークにはSpring Bootを使って構築していきます。

- [Kotlin 1.0.5](https://kotlinlang.org/)
- [IntelliJ IDEA Community Edition](https://www.jetbrains.com/idea/)
- [Spring Boot](https://projects.spring.io/spring-boot/)
- [Google App Engine](https://cloud.google.com/appengine/)

すぐに開発をはじめたい方や完成したプロジェクトを見たい方はソースコードをGitHubで公開しているので参考にして頂ければと思います。
https://github.com/t-kashima/kotlin_on_gae

それではさっそく1つずつ環境を作っていきます。

## IntelliJ IDEAでプロジェクトを作る

まずはKotlinを書くエディタとしてIntelliJ IDEAを使ってきます。IntelliJ IDEAのページからダウンロードしてインストールしてください。
https://www.jetbrains.com/idea/

次にIntelliJ IDEAにKotlinプラグインをインストールします。IntelliJ IDEAのPreferences→Plugins→Install JetBrains Pluginを選び、Kotlinを検索してインストールしてください。

<img src="https://d2mxuefqeaa7sj.cloudfront.net/s_C60E80387735160DE8E8BBB4F7C810A7A9D8CF5BCFF569278689868CA923920B_1481384299846_+2016-12-11+0.37.52.png">

次にこれから開発をしていくプロジェクトを作成します。IntelliJ IDEAのFile→New→Projectを選び、GradleのKotlinを選んで次に進んでください。以下の画面が表示されたらVersionに今リリースされているKotlinの最新バージョンである1.0.5を入力して進んでください。

<img src="https://d2mxuefqeaa7sj.cloudfront.net/s_C60E80387735160DE8E8BBB4F7C810A7A9D8CF5BCFF569278689868CA923920B_1481384707424_+2016-12-11+0.45.00.png">

いくつか画面が表示されますがどんどん進んで、最後に保存場所を入力する画面になるので保存場所を入力して完了を押すとプロジェクトが作成されます。

これでIntelliJ IDEAで開発する準備が整いました。

## Spring Bootを使ってローカル環境を作る

次にフレームワークであるSpring Bootを使って、ローカル環境を構築するまでをやっていきます。

まずSpring BootとKotlinで開発できるように先ほどのプロジェクトをIntelliJ IDEAで開いて、build.gradleを以下のように書き替えます。


```groovy:build.gradle
buildscript {
    ext.kotlin_version = '1.0.5'

    repositories {
        mavenCentral()
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "org.springframework.boot:spring-boot-gradle-plugin:1.4.2.RELEASE"
    }
}

apply plugin: "kotlin"
apply plugin: "org.springframework.boot"

repositories {
    mavenCentral()
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

sourceSets {
    main.java.srcDirs += 'src/main/kotlin'
}

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    compile "org.springframework.boot:spring-boot-starter-web"
}
```



次に `src/main/kotlin` にパッケージを作成し(今回の例ではhelloとしています)、その中にApplication.ktとHelloController.ktを作成します。以下の画像のようになると思います。

<img src="https://d2mxuefqeaa7sj.cloudfront.net/s_C60E80387735160DE8E8BBB4F7C810A7A9D8CF5BCFF569278689868CA923920B_1481464849792_+2016-12-11+22.59.23.png">

Application.ktとHelloController.ktにはそれぞれ次のように書いてください。
HelloControllerにはどのパスでアクセスがきたらメソッドを呼び出すかを指定しています。今回の場合だと`/` にアクセスがあるとindexメソッドが呼ばれ「Greetings from Spring Boot!」が表示されます。

```groovy:Application.kt
package hello

import java.util.Arrays

import org.springframework.boot.CommandLineRunner
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.context.ApplicationContext
import org.springframework.context.annotation.Bean

@SpringBootApplication
open class Application {
    companion object {
        @JvmStatic
        fun main(args: Array<String>) {
            SpringApplication.run(Application::class.java, *args)
        }
    }
}
```

```groovy:HelloController.kt
package hello

import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RestController
class HelloController {
    @RequestMapping("/")
    fun index(): String {
        return "Greetings from Spring Boot!"
    }
}
```


これでKotlinとSpring Bootの準備が整ったので、さっくローカル環境を立ち上げてみます。Application.ktを右クリックして「Run〜」を選んでください。そうするとビルドが始まり、少し時間はかかりますがビルドが終わるとローカル環境が立ち上がります。

ブラウザに`http://localhost:8080` を入力して「Greetings from Spring Boot!」が表示されればローカル環境が無事に立ち上がっています。

## Google App EngineでSpring Bootを動かす

最後にプロジェクトをGoogle App Engineにデプロイして外からもアクセスできるようにしていきます。

そのためにまずGoogle App Engineのアカウントを作る必要があります。以下のサイトにアクセスしてアカウントを作り、その後デプロイ先のプロジェクトを作ってください。
https://cloud.google.com/appengine/

Google App Engineのプロジェクトが作れたらローカルから色々設定できるようにgcloudコマンドをインストールしてデプロイの設定をします。次のサイトからダウンロードしてインストールしてください。
https://cloud.google.com/sdk/gcloud/

インストールができたらターミナルで次のコマンドを実行して、Google App Engineのアカウントとプロジェクトを設定をします。<PROJECT_ID>はGogole App Engineで作ったプロジェクトのIDに変えてください。

```sh:
$ gcloud auth login
$ gcloud config set project <PROJECT_ID>
```

次にGradleからGoogle App Engineにデプロイできるようにプラグインを追加します。build.gradleを次のように編集してください。

```groovy:build.gradle
buildscript {
    ext.kotlin_version = '1.0.5'

    repositories {
        mavenCentral()
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "org.springframework.boot:spring-boot-gradle-plugin:1.4.2.RELEASE"
        classpath "com.google.cloud.tools:appengine-gradle-plugin:+"
    }
}

apply plugin: "kotlin"
apply plugin: "com.google.cloud.tools.appengine"
apply plugin: "org.springframework.boot"

repositories {
    mavenCentral()
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

sourceSets {
    main.java.srcDirs += 'src/main/kotlin'
}

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    compile "com.google.appengine:appengine:+"
    compile "org.springframework.boot:spring-boot-starter-web"
}
```


またGoogle App Engineは標準環境ではJava8に対応していないので、フレキシブル環境というのを使います。`src/main/appengine`を作成して、その中に次のように書いたapp.yamlを追加してください。

```yaml:app.yaml
runtime: java
env: flex
```


さらにIntelliJ IDEAからデプロイできるようIntelliJ IDEAのRun→Edit Configuresを選び、Gradleのタスクを追加してTasksに「appengineDeploy」を設定します。

<img src="https://d2mxuefqeaa7sj.cloudfront.net/s_C60E80387735160DE8E8BBB4F7C810A7A9D8CF5BCFF569278689868CA923920B_1481389951421_+2016-12-11+2.11.56.png">

OKを押してこの設定をRunから動かしてみます。するとビルド後にGoogle App Engineへのデプロイが行われます。初回はデプロイが終わるまでかなり時間がかかります。そしてデプロイが終わると、ターミナルで以下のコマンドを実行してブラウザで見れることを確認してみましょう！

```sh
$ gcloud app browse
```

「Getting from Spring Boot!」の文字が表示されていれば成功です。また、Google App Engineのダッシュボードを見ると次のようにインスタンスが立ち上がってることが確認できます。

<img src="https://d2mxuefqeaa7sj.cloudfront.net/s_C60E80387735160DE8E8BBB4F7C810A7A9D8CF5BCFF569278689868CA923920B_1481390379641_+2016-12-11+2.19.30.png">

あとはプロジェクトのHelloController.ktを編集すればどのパスにアクセスがあればどんなことをするというのが書けるので、それをローカルで確認して同じようにデプロイすればどんどん開発を進めていけます。

## おわりに

長くなってしまいましたが、いかがだったでしょうか。
意外とMavenを使わずにGradleだけで環境を作っている例が少なく、普段Gradleを使っていて慣れてしまっているのでこの方法を見つけるまでに色々とはまってしまいました。
まだ開発の方は全然進められていないので、[Kotlin Advent Calendar](http://qiita.com/advent-calendar/2016/kotlin)の記事も参考にしてこれからどんどん開発していこうと思います！

## 参考にしたサイト

- [Deploy Spring Boot Application in App Engine](https://codelabs.developers.google.com/codelabs/cloud-app-engine-springboot/index.html)


- [Gradle で GAE/J 開発](http://qiita.com/kumazo/items/7eeb83926a4265fb8d39)