Micronaut 2.x 入門

先日、[Micronaut フレームワークの採用を促進するために Micronaut 財団を設立](https://www.infoq.com/jp/news/2020/08/oci-micronaut-foundation/?itm_source=infoq&itm_medium=related_content_link&itm_campaign=relatedContent_news_clk)すると発表されました🎉

これにより、どんどんMicronautが流行っていくと思われます！

最近サーバレスファンクションやコンテナサービスによるオートスケールで運用することが多くなってきたことから、コールドスタートが問題視されるJVM言語は利用が難しいのでは？という声も聞こえてきます..。

ですが、Micronautを始めとするJVM系のフレームワークがネイティブビルドに対応していくことでJVM言語が採用しやすくなりそうです。


## そもそもMicronautって何？

[Micronaut公式](https://micronaut.io/)から引用

> A modern, JVM-based, full-stack framework for building modular, easily testable microservice and serverless applications.

モジュール式でテストが容易なマイクロサービスやサーバーレスアプリケーションを構築するための、モダンなJVMベースのフルスタックフレームワークです。

* Java, Groovy, Kotlinで記述可能
* GraalVMというアプリケーションをネイティブマシンコードに変換してくれる仕組みを使い、コールドスタートであるJVM言語を数十ミリ秒で起動可能
* デフォルトで `AWS Lambda` や `GCP Cloud Functions` などのFunctions as a Service（FaaS）に対応
* CLIにより簡単にMicronautプロジェクトの構築が可能
  * FaaSプロジェクトの作成も簡単！



## Version

最近[version: 2.0](https://micronaut.io/blog/2020-06-26-announcing-micronaut-20.html)がリリースされました🎉
まだリリースされてから2年ほどしか立っていない新しいフレームワークです。



## 試してみる

### 環境

* macOS Catalina 10.15.4
* メモリ16GB

  

### SDKMANのインストール

JVMの開発環境を作成するためのツールであるSDKMANを使ってJavaの環境を作っていきましょう。
[SDKMAN公式](https://sdkman.io/install) の Installationに沿って進めていきます。

```bash
# SDKMANを取得
$ curl -s "https://get.sdkman.io" | bash
# ターミナルに読み込ませる
$ source "$HOME/.sdkman/bin/sdkman-init.sh"
# SDKMANがインストールされていることを確認
$ sdk version
SDKMAN 5.8.2+493
```



続いてJDKのインストールを行なっていきます。
Micronaut Ver2.0でJava14に対応したのでせっかくなので14を入れていきましょう。

```bash
# インストールできるJDKの一覧
$ sdk list java
================================================================================
 Vendor        | Use | Version      | Dist    | Status     | Identifier
--------------------------------------------------------------------------------
 AdoptOpenJDK  |     | 14.0.2.j9    | adpt    |            | 14.0.2.j9-adpt
               |     | 14.0.2.hs    | adpt    |            | 14.0.2.hs-adpt
               |     | 13.0.2.j9    | adpt    |            | 13.0.2.j9-adpt
               |     | 13.0.2.hs    | adpt    |            | 13.0.2.hs-adpt
               |     | 12.0.2.j9    | adpt    |            | 12.0.2.j9-adpt
               |     | 12.0.2.hs    | adpt    |            | 12.0.2.hs-adpt
               |     | 11.0.8.j9    | adpt    |            | 11.0.8.j9-adpt
               |     | 11.0.8.hs    | adpt    |            | 11.0.8.hs-adpt

# java14をインストール そのままデフォルトに設定
$ sdk install java 14.0.2.hs-adpt

# javaがインストールされていることを確認
$ java --version
openjdk 14.0.2 2020-07-14
OpenJDK Runtime Environment AdoptOpenJDK (build 14.0.2+12)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 14.0.2+12, mixed mode, sharing)
```



### Micronautのインストール

先ほどインストールしたSDKMANを使ってインストールしていきます。

```bash
$ sdk install micronaut
Installing: micronaut 2.0.1
Done installing!
Do you want micronaut 2.0.1 to be set as default? (Y/n): Y
Setting micronaut 2.0.1 as default.
```



インストールできたかCLIを使って確認しましょう。

```bash
$ mn -V
Micronaut Version: 2.0.1
```



### アプリケーションの作成

まずは作業用ディレクトリを作成し移動します。

```bash
$ mkdir introduction && cd introduction
```

CLIを使ってアプリケーションを作成していきましょう。
mnコマンドで対話式に進めていきます。
helpオプションで使い方が確認できます。

```bash
$ mn

mn> --help
Usage: mn [-hvVx] [COMMAND]
Micronaut CLI command line interface for generating projects and services.
Application generation commands are:

*  create-app NAME
*  create-cli-app NAME
*  create-function-app NAME
*  create-grpc-app NAME
*  create-messaging-app NAME

Options:
  -h, --help         Show this help message and exit.
  -v, --verbose      Create verbose output.
  -V, --version      Print version information and exit.
  -x, --stacktrace   Show full stack trace when exceptions occur.

Commands:
  create-app            Creates an application
  create-cli-app        Creates a CLI application
  create-function-app   Creates a Cloud Function
  create-grpc-app       Creates a gRPC application
  create-messaging-app  Creates a messaging application
```



今回は通常のアプリケーションを構築したいので `create-app`を使っていきましょう。
最近kotlinにハマっているのでkotlinを指定します。（--langを未指定の場合はJavaが選択されます）

```bash
mn> create-app introduction-app --lang=kotlin
| Application created at introduction-app
```

対話モードを抜けましょう

```bash
mn> exit
```

アプリが作成されているか確認しましょう

```
$ tree introduction-app/
introduction-app/
├── Dockerfile
├── README.md
├── build.gradle
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── micronaut-cli.yml
├── settings.gradle
└── src
    ├── main
    │   ├── kotlin
    │   │   └── introduction
    │   │       └── app
    │   │           └── Application.kt
    │   └── resources
    │       ├── application.yml
    │       └── logback.xml
    └── test
        └── kotlin
            └── introduction
                └── app
                    └── IntroductionAppTest.kt
12 directories, 14 files
```

作成されていますね！デフォルトでDockerfileが生成されるのが面白いですね。
作成したプロジェクトはIntelliJ IDEAなどで開きましょう。



### APIを作ってみよう

今回はサンプルなので、introduction.app直下にcontrollerを配置しましょう。

```bash
src
├── main
│   ├── kotlin
│   │   └── introduction
│   │       └── app
│   │           ├── Application.kt
│   │           └── HelloController.kt
```

```kotlin:HelloController.kt
package introduction.app

import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import io.micronaut.http.annotation.PathVariable

@Controller("api/v1")
class HelloController {

    @Get("/hello")
    fun helloWorld(): String {
        return "hello world!"
    }

    @Get("/hello/{name}")
    fun helloName(@PathVariable name: String): String {
        return "hello $name!"
    }
}
```



そのまま実行してもいいですが、せっかくなのでビルドしてJarファイル経由で実行してみましょう。

```bash
# 作成したプロジェクトに移動
$ cd introduction-app

# ビルド
$ ./gradlew assemble

# 生成したjarファイルを実行
$ java -jar ./build/libs/introduction-app-0.1-all.jar
05:43:15.853 [main] INFO  io.micronaut.runtime.Micronaut - Startup completed in 948ms. Server Running: http://localhost:8080
```



curlでAPIを叩こう

```bash
# helloWorld()をコール
$ curl http://localhost:8080/api/v1/hello
hello world!

# helloName()をコール
$ curl http://localhost:8080/api/v1/hello/micronaut
hello micronaut!
```

意図した通りに返却されました！



## まとめ

簡単に導入から実行まで確認できました！
記述方法もSpring Bootに似ているためわかりやすいです。
今回生成したjarファイルを、プロジェクト作成時に作られたDockerfileを元に Amazon ECS（Amazon Elastic Container Service）で動かすことも出来ます。

次回はAWS Lambdaの上で動かし、気になる起動時間を見ていきたいと思います。



## 参考文献

この記事は以下の情報を参考にして執筆しました。

- [Micronaut公式](https://micronaut.io/)
- [Micronaut フレームワークの採用を促進するために Micronaut 財団を設立](https://www.infoq.com/jp/news/2020/08/oci-micronaut-foundation/?itm_source=infoq&itm_medium=related_content_link&itm_campaign=relatedContent_news_clk)
- [Micronaut 2.0 がツールを強化し、サーバレスと GraalVM のサポートを強化](https://www.infoq.com/jp/news/2020/08/micronaut-v2/)