Micronaut で Hello World on Windows

WindowsMicronaut を試してみたので備忘録。

インストール

一般的には SDKMAN を使うケースが多いかと思いますが、今回は Windows 環境ということでバイナリを使います。ダウンロードして Path を通す。

2.1.2 Install through Binary on Windows

初回の mn コマンド実行時に依存解決する模様。無念にもプロキシ環境の場合は事前に設定する。

$ set MN_OPTS=-Dhttps.proxyHost=proxy.com -Dhttps.proxyPort=8080

mn コマンドを叩いてみる。

$ mn --version
| Micronaut Version: 1.0.1
| JVM Version: 1.8.0_172

プロジェクト作成

無念にもプロキシ環境の場合は事前に設定する。

$ set JAVA_OPTS=-Dhttps.proxyHost=proxy.com -Dhttps.proxyPort=8080

プロジェクト作成。

$ mn create-app micronaut-examples
| Generating Java project...
| Application created at C:\Users\ ... \micronaut-examples

起動。

$ cd micronaut-examples
$ gradlew run
> Task :run
[main] INFO  io.micronaut.runtime.Micronaut - Startup completed in 2238ms. Server Running: http://localhost:8080

環境起因なのか、起動は思っていたほど早くない気がする...?

Controller 作成

CLI から Controller を作成すると、Controller クラスとテストクラスが生成される。

$ mn create-controller Hello
| Rendered template Controller.java to destination src\main\java\micronaut\examples\HelloController.java
| Rendered template ControllerTest.java to destination src\test\java\micronaut\examples\HelloControllerTest.java

デフォルトでは 200 OK を返すコードが生成される。

@Controller("/hello")
public class HelloController {
    @Get("/")
    public HttpStatus index() {
        return HttpStatus.OK;
    }
}

gradlew run で起動して、http://localhost:8080/hello にアクセスするとレスポンスが返る。

テストクラスはこちら。gradlew test でテストを実行する。

public class HelloControllerTest {
    @Test
    public void testIndex() throws Exception {
        try(EmbeddedServer server = ApplicationContext.run(EmbeddedServer.class)) {
            try(RxHttpClient client = server.getApplicationContext().createBean(RxHttpClient.class, server.getURL())) {
                assertEquals(HttpStatus.OK, client.toBlocking().exchange("/hello").status());
            }
        }
    }
}

Controller のメソッドとテストを追加してみる。

@Get("hello2")
public HttpResponse<String> index2() {
    return HttpResponse.ok("Hello Micronaut");
}

テストメソッドはこんな感じ。

@Test
public void testIndex2() throws Exception {
    try(EmbeddedServer server = ApplicationContext.run(EmbeddedServer.class)) {
        try(RxHttpClient client = server.getApplicationContext().createBean(RxHttpClient.class, server.getURL())) {
            assertEquals("Hello Micronaut", client.toBlocking().exchange("/hello2", String.class).body());
        }
    }
}

最初、自動生成されたテストコードを参考に HttpResponse#exchange(String) で試してみたが、これだとどうしてもレスポンスボディが取得できない...。で、HttpResponse#exchange(String, Class<T>) でレスポンスの型を指定してみたら無事に取得できた。

client.toBlocking().exchange("/hello2").body() //=> null
client.toBlocking().exchange("/hello2", String.class).body() //=> "Hello Micronaut"

API ドキュメント にもそのような感じのことが書いてあるっぽいが、これは Reactive Streams の仕様なんだろうか...。

Returns: An Optional of the type or Optional.empty() if the body cannot be returned as the given type

ビルド

以下のコマンドを叩くと、build フォルダにいろいろ生成される。

$ gradlew assemble

その他

とりあえず、動かすことはできました。ドキュメントは割と充実しているようなので読んでみたいと思います。

User Guide - MICRONAUT DOCUMENTATION

Micronaut は、起動の早さや省メモリが特徴のようで、クラウド環境、特にサーバーレスな環境で Java アプリケーションを使うときに適しているようです。クラウド以外にも、起動が早いということからバッチアプリケーションとして使えるかもしれません。このあたり、Spring Batch と比較してみようかなー。