Micronaut Reactive HTTP Request Processing
Since Micronaut is built on Netty, it is possible to perform non-blocking I / O.
Reactive HTTP Request Processing
If your controller method returns a non-blocking type such as an RxJava Observable or a CompletableFuture then Micronaut will use the Event loop thread to subscribe to the result.
When the Controller
method returns the RxJava ʻObservable or
CompletableFuture, it uses the Event loop thread to subscribe to the
Controller` result.
If however you return any other type then Micronaut will execute your @Controller method in a preconfigured I/O thread pool.
If it returns any other type, it will use the I / O thread pool.
The return type of Controller
is important, isn't it?
Well, it's easy, but let's use it.
Click here for this environment.
$ mn -V
| Micronaut Version: 1.0.4
| JVM Version: 1.8.0_191
For the time being, create a template project.
$ mn create-app hello-reactive --build maven
$ cd hello-reactive
Leave the class with the main
method as it is for the time being
src/main/java/hello/reactive/Application.java
package hello.reactive;
import io.micronaut.runtime.Micronaut;
public class Application {
public static void main(String[] args) {
Micronaut.run(Application.class);
}
}
Let's make Controller
.
src/main/java/hello/reactive/HelloReactiveController.java
package hello.reactive;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;
import io.micronaut.http.MediaType;
import io.micronaut.http.annotation.Body;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.annotation.Post;
import io.reactivex.Flowable;
import org.reactivestreams.Publisher;
@Controller("/reactive")
public class HelloReactiveController {
}
Let's write the contents of the method.
First, let's check the documentation to see what type to return.
org.reactivestreams.Publisher
Single
and ʻObservable`Mono
and Flux
java.util.concurrent.CompletableFuture
It seems like that.
In addition, it seems that you can use CompletableFuture
or Reactive type for method arguments.
Let's create a text / event-stream
method that returns a message every second.
@Get(value = "/hello", produces = MediaType.TEXT_EVENT_STREAM)
public Publisher<String> hello() {
return Flowable
.fromArray("Hello Reactive")
.repeat(10)
.delay(1, TimeUnit.SECONDS)
.map(m -> String.format("[%s] %s", LocalDateTime.now(), m));
}
When I checked the dependency of the created project, I found RxJava, so I used this.
$ ./mvnw dependency:tree
[INFO] +- io.micronaut:micronaut-runtime:jar:1.0.4:compile
[INFO] | +- io.micronaut:micronaut-aop:jar:1.0.4:compile
[INFO] | +- com.fasterxml.jackson.core:jackson-databind:jar:2.9.8:compile
[INFO] | | +- com.fasterxml.jackson.core:jackson-annotations:jar:2.9.8:compile
[INFO] | | \- com.fasterxml.jackson.core:jackson-core:jar:2.9.8:compile
[INFO] | +- io.reactivex.rxjava2:rxjava:jar:2.2.2:compile
Start and check.
$ curl -i localhost:8080/reactive/hello
HTTP/1.1 200 OK
transfer-encoding: chunked
Date: Wed, 20 Feb 2019 13:00:07 GMT
transfer-encoding: chunked
content-type: text/event-stream
data: [2019-02-20T13:00:08.861] Hello Reactive
data: [2019-02-20T13:00:09.940] Hello Reactive
data: [2019-02-20T13:00:10.943] Hello Reactive
data: [2019-02-20T13:00:11.946] Hello Reactive
data: [2019-02-20T13:00:12.948] Hello Reactive
data: [2019-02-20T13:00:13.950] Hello Reactive
data: [2019-02-20T13:00:14.953] Hello Reactive
data: [2019-02-20T13:00:15.954] Hello Reactive
data: [2019-02-20T13:00:16.956] Hello Reactive
data: [2019-02-20T13:00:17.959] Hello Reactive
Somehow, it works like that.
Let's write something that takes an argument.
@Post(value = "echo", consumes = MediaType.TEXT_PLAIN, produces = MediaType.TEXT_EVENT_STREAM)
public Publisher<String> echo(@Body Flowable<String> text) {
return text.map(t -> "★" + t + "★");
}
The input isn't streamed either ...
$ curl -i -XPOST -H 'Content-Type: text/plain' localhost:8080/reactive/echo -d 'hello'
HTTP/1.1 200 OK
transfer-encoding: chunked
Date: Wed, 20 Feb 2019 13:01:29 GMT
transfer-encoding: chunked
content-type: text/event-stream
data: ★hello★
Is it okay to put Reactor in the dependency?
For the time being, I was able to make a simple confirmation.
Recommended Posts