この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
What is Micronaut?
Micronaut(まいくろのーと)とは、JVMベースのフルスタックフレームワークです。
2018年5月にOSSとして公開され、先日最新バージョンの1.1がリリースされました。
Java/Groovy/Kotlinで実装することができ、テストしやすくコンテナ化も容易、
クラウドネイティブなアプリも簡単に構築できるようです。
Features of Micronaut
Micronautの主な特徴について、ここで説明している内容から抜粋して紹介します。
Fast start up & low memory consumption
リフレクションベースのIoCフレームワークだと、
すべてのフィールドやメソッドのリフレクションデータをロードしてキャッシュしますが、
Micronautではアプリケーションのコードベースのサイズに左右されないので、
起動が速く、メモリ消費も少なくすることができます。
Micronaut usging Graal VM
Micronautは、リフレクションを使用しないDIとAOPランタイムを持っているので、
アプリをGraalVM上で実行することが容易です。
GraalVMを使用すれば、わずか数十ミリ秒でMicronautアプリが起動します。
* GraalVM : Oracleの汎用VM.Javaアプリをネイティブのマシンコードにコンパイルする機能を持つ
fast & easy Testing
Unitテストでサーバを簡単に起動し、すぐに実行可能です。
import io.micronaut.runtime.server.EmbeddedServer
import spock.lang.*
class HelloClientSpec extends Specification {
@Shared
@AutoCleanup
EmbeddedServer embeddedServer =
ApplicationContext.run(EmbeddedServer)
@Shared
HelloClient client = embeddedServer
.applicationContext
.getBean(HelloClient)
void "test hello world response"() {
expect:
client.hello().blockingGet() == "Hello World"
}
}
compile time DI & AOP
Micronautではリフレクションを使わずにコンパイル時のAOPを提供しています。
だからGraalVMとかでも簡単に動かせるんですね。
@Scheduled(fixedRate = "5m")
@Retry(attempts='5')
void everyFiveMinutes() {
messageService.sendMessage("Hello World");
}
Build Reactive application
Micronautは、Reactive Streamを実装するフレームワーク(RxJavaとか)をサポートします。
@Client( id = "person-service" )
public interface PersonClient {
public io.reactivex.Single<Person>
save(@Body Single<Person>person)
}
Micronaut Profiles
Micronautにはデフォルトで複数のプロファイルが組み込まれています。
プロファイルを使うことでアプリの雛形を生成したり、
対象プロファイル用のコマンドを使用することができます。
これは、後述するcreate-appコマンド(Micronautアプリを生成するコマンド)を使った場合、
コントローラ(create-controller)、クライアント(create-client)を
生成するためのコマンドが使えるようになったりします。
Clound Native
MicronautではGoogle Cloud Platform(GCP)やAmazon Web Services(AWS)を
統合したモジュールを提供しています。
これらを用いることにより、各種クラウドプラットフォームに対応したMicronautアプリを作成できます。
参考: Micronaut GCP Micronaut AWS
また、Micronaut AWSを使うと、AWS Lambdaを使ったMicronautアプリを作成することができます。
(Alexa SkillsとかAWS API Gatewayもサポート)
message driven
RabbitMQを統合したMicronaut RabbitMQモジュールを使えば、
Micronautアプリでメッセージ駆動型サービスが作成可能になります。
また、RabbitMQプロファイルを使用すれば、
producerとlistenerを作成する固有コマンドを使うことができます。
% mn create-app sample-mq-service --profile rabbitmq
% mn create-rabbitmq-producer Message # make producer
% mn create-rabbitmq-listener Message # make listener
develop serverless application
さきほどMicronaut AWSモジュールでLambdaアプリが開発できるといいました。
Micronautの、コンパイルタイムDI&AOPであればサーバーレス用関数を書くのに適しています。
@Field
@Inject
HelloService helloService
Message hello(Person person) {
helloService.hello(person)
}
resilient microService
分散環境における障害対策であるとサーキットブレーカーなどの機能がデフォルトで組み込まれています、
import io.micronaut.retry.annotation.*
@CircuitBreaker(reset = "30s")
public List findBooks() {
...
..
}
環境
今回使用した動作環境は以下のとおりです。
- OS : MacOS X 10.12.6
- Java : 1.8.0_212
Setup Micronaut
ではMicronautをインストールしてみましょう。
sdkmanを使うと簡単にセットアップできるので、まずはsdkmanをインストールします。
% curl -s "https://get.sdkman.io" | bash
% sdk version
SDKMAN 5.7.3+337
次に、micronautをインストールします。
% sdk install micronaut
==== BROADCAST =================================================================
* 2019-07-13: Groovy 3.0.0-beta-2 released on SDKMAN! #groovylang
* 2019-07-11: Grails 4.0.0 released on SDKMAN! #grailsfw
* 2019-07-10: Gradle 5.5.1 released on SDKMAN! #gradle
================================================================================
Downloading: micronaut 1.1.4
In progress...
######################################################################## 100.0%
Installing: micronaut 1.1.4
Done installing!
Setting micronaut 1.1.4 as default.
mnコマンドが使えるようになっていればMicronautのインストールは完了です。
% mn --version
Resolving dependencies..
| Micronaut Version: 1.1.4
| JVM Version: 1.8.0_212
Hello Micronaut
Micronautアプリを作成してみましょう。
mn create-appコマンドを使えばシンプルなプロジェクトを生成できます。
% mn create-app example.micronaut.complete
| Generating Java project...
| Application created at /path/your/micronaut/complete
生成したプロジェクトはgradleをつかったプロジェクトとなっています。
IDEA等のIDEを使えば、そのまま開いて編集することが可能です。
最初にシンプルなControllerを作成します。
このControllerは/hello宛のGETリクエストを受けると文字列を返します。
// path/your/prject/complete/src/main/java/example/micronaut/HelloController.java
package example.micronaut;
import io.micronaut.http.MediaType;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.annotation.Produces;
@Controller("/hello")
public class HelloController {
@Get("/")
@Produces(MediaType.TEXT_PLAIN)
public String index() {
return "Hello World";
}
}
Controllerに対するテストも作成してみましょう。
@MicronautTestを使えばテストも簡単に作成可能です。
// path/your/prject/complete/src/test/java/example/micronaut/HelloControllerTest.java
package example.micronaut;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import io.micronaut.http.HttpRequest;
import io.micronaut.http.client.RxHttpClient;
import io.micronaut.http.client.annotation.Client;
import io.micronaut.test.annotation.MicronautTest;
import org.junit.jupiter.api.Test;
import javax.inject.Inject;
@MicronautTest
public class HelloControllerTest {
@Inject
@Client("/")
RxHttpClient client;
@Test
public void testHello() {
HttpRequest<String> request = HttpRequest.GET("/hello");
String body = client.toBlocking().retrieve(request);
assertNotNull(body);
assertEquals("Hello World", body);
}
}
gradleでtestを実行してみます。
% ./gradlew test
Starting a Gradle Daemon, 1 incompatible Daemon could not be reused, use --status for details
> Task :test
BUILD SUCCESSFUL in 39s
4 actionable tasks: 2 executed, 2 up-to-date
runコマンドで起動してみましょう。
% ./gradlew run
> Task :run
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
17:12:14.213 [main] INFO io.micronaut.runtime.Micronaut
- Startup completed in 6380ms. Server Running: http://localhost:8080
> :run
Controllerにcurlでアクセスしてみます。
%curl http://localhost:8080/hello
Hello World
まとめ
今回はJVMベースのフルスタックフレームワーク、Micronautを少しだけ使ってみました。
機能説明でいったとおり、MicronautではCloud用モジュールが用意されていたり
GraalVMで動かしたりも可能なので、いろいろと試して見ようかと思います。
参考サイト
infoq : https://www.infoq.com/jp/news/2019/07/micronaut-1.1-cloud-native
Micronaut公式 : https://micronaut.io/