Kotlinでwebアプリ作成してHerokuにデプロイ

# はじめに

先日Kotlin1.3がリリースされました。
これからは、Kotlinが来るんじゃないかと思い、入門してみます。

# 目標

以下を順に行います。

+ Javaのインストール
+ Spring Initializrでひな形作成
+ 設定ファイルの修正
+ プログラムとテンプレートの作成
+ Herokuでのデプロイ

# 環境

ベースがJavaなので、Javaさえ動けば何とかなるかと思います。
今回はCloud9(Blank)で環境構築します。
なお、Cloud9のOSは ubuntu 14.04 と古いです。

# 環境構築

## Javaインストール

デフォルトでインストールしてあるJavaはバージョンが1.7です。

```
$ java -version
java version "1.7.0_151"
OpenJDK Runtime Environment (IcedTea 2.6.11) (7u151-2.6.11-0ubuntu1.14.04.1)
OpenJDK 64-Bit Server VM (build 24.151-b01, mixed mode)
```

今回はSpring Boot 2を利用するため、8以上が必須です。
そのため、最新のJava11をインストールします。

リポジトリの追加

```
sudo add-apt-repository ppa:linuxuprising/java
```

アップデート＆インストール

```
sudo apt update
sudo apt install openjdk-11-jdk
```

途中で、Oracleのライセンスの画面がでますので、画面の指示に従ってください。

```
$ java -version
java version "11.0.1" 2018-10-16 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.1+13-LTS)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.1+13-LTS, mixed mode)
```

# Spring Initializrでひな形作成

[Spring Initializr](https://start.spring.io/)でひな形を作成します。


Generate a [Gradle Project] with [Kotlin] and Spring Boot [2.1.0]

DependenciesはWebとThymeleafを選択してください。

「Generate Project alt + ⏎」
でひな形がダウンロードできます。
その後、任意のフォルダに展開してください。

※ curlでダウンロードしたほうが簡単かもしれません。

```
curl https://start.spring.io/starter.tgz -d type=gradle-project -d language=kotlin -d dependencies=web,thymeleaf | tar xvfz -
```

各種パラメータはこちらで確認できます。

```
curl start.spring.io
```

# ファイルの修正

ひな形のKotlinは1.2.70になります。
せっかくなので、最新版の1.3.0にしましょう。

build.gradleの最初のほうに、Kotlinのバージョンが指定していあるので、そこを変更してください。

```build.gradle
buildscript {
	ext {
		kotlinVersion = '1.2.70' # ここを'1.3.0'にする
		springBootVersion = '2.1.0.RELEASE'
	}
~ 以下省略 ~
```

# コンパイル＆実行

展開したフォルダで以下を実行するだけです。
必要なモジュールをダウンロードしたりコンパイルしたりして実行してくれます。

```
./gradlew bootRun
```

実行したら、試しにアクセスしてみてください。
Cloud9だと、自動的にアプリケーションリンクになります。
ローカル環境の場合は、localhost:8080にアクセスしましょう。

すると、まだコントローラーなどをコーディングしていないので、エラー画面が表示されます。

```
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.

Tue Nov 13 02:42:09 UTC 2018
There was an unexpected error (type=Not Found, status=404).
No message available
```

# プログラムとテンプレートの作成

プログラム(コントローラー)として、以下のファイルを作成します。

```src/main/kotlin/com/example/demo/Hello.kt
package com.example.demo

import org.springframework.stereotype.Controller
import org.springframework.ui.Model
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestParam

@Controller
class Hello {
    @GetMapping("/")
    fun hello(
        @RequestParam(value = "name", required = false, defaultValue = "world") name: String,
        model: Model): String {
        model.addAttribute("name", name)
        return "index"
    }
}
```

htmlテンプレートとして、以下のファイルを作成します。

```src/main/resources/templates/index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8" http-equiv="Content-Type" content="text/html" />
    <title>Getting Started: Saving Web Content</title>
</head>
<body>
    <p th:text="'Hello, ' + ${name} + '!'" />
    <form action="." method="get">
        <input type="text" name="name">
    </form>
</body>
</html>
```

再度コンパイル＆実行します。

```
./gradlew bootRun
```

画面に、「Hello, world!」が表示されます。
テキストボックスに名前を入れると、入力した名前が表示されます。

# Herokuへのデプロイ

## 設定ファイル追加

以下のファイルを修正＆追加します。

```src/main/resources/application.properties
server.port=${PORT:5000}
```

```:Procfile
web: java -jar build/libs/demo-0.0.1-SNAPSHOT.jar
```

## herokucliインストール

ubuntuならこれだけです。

```
sudo apt install heroku
```

## herokuアカウント作成

アカウントがない人はこちらから作成してください。
https://signup.heroku.com/
gmailを利用している場合には、
いつものアドレス+xxx@gmail.comとすることにより、複数アカウントが作成できます。
確認メールが届いたら、パスワードを設定してください。

## デプロイ

ログインして

```
$ heroku login
Enter your Heroku credentials:
Email: xxxxx@mail.xxx
Password: *************
Logged in as xxxxx@mail.xxx
```

ローカルにgitリポジトリを作成して

```
git init
git add .
git commit -m "first commit"
```

herokuアプリケーションを作成して、pushしましょう。

```
heroku create
git push heroku master
```

しばらく待つと、remoteでbuildしてデプロイしてくれます。

成功すると、以下のようなログが出力されます。

```
remote:        
remote:        BUILD SUCCESSFUL in 34s
remote:        4 actionable tasks: 4 executed
remote: -----> Discovering process types
remote:        Procfile declares types     -> (none)
remote:        Default types for buildpack -> web
remote: 
remote: -----> Compressing...
remote:        Done: 69.5M
remote: -----> Launching...
remote:        Released v3
remote:        https://xxx-xxx-xxx.herokuapp.com/ deployed to Heroku
remote: 
remote: Verifying deploy... done.
To https://git.heroku.com/xxx-xxx-xxx.git
 * [new branch]      master -> master
```

あとは、好きに改造してみてください。

# 終わりに

今まで、Java系はとっつきにくい気がして敬遠してましたが、Spring Bootを使うとあっという間にできてびっくりしました。
食わず嫌いはダメですね。

herokuもgradleの情報が少なかったですが、何も考えずにpushしたらできちゃいました。
これから利用していきたいと思います。

# 参考にしたページ

- [Spring Boot (Kotlin) はじめの一歩](https://qiita.com/Yuki10/items/aef152f300a500b85725)