@ -69,51 +74,90 @@ Each runtime is adapted to a set of shared, reactive `ServerHttpRequest` and
@@ -69,51 +74,90 @@ Each runtime is adapted to a set of shared, reactive `ServerHttpRequest` and
as `Flux<DataBuffer>` with full backpressure support on the read and the
write side.
The `spring-core` module provides reactive `Encoder` and `Decoder` contracts
that enable the serialization of a `Flux` of bytes to and from typed objects.
The `spring-web` module adds JSON (Jackson) and XML (JAXB) implementations for use in
web applications as well as others for SSE streaming and zero-copy file transfer.
JSON or XML REST webservices are supported, as well as view rendering, server-sent events
and Websocket.
The `spring-web-reactive` module contains the Spring Web Reactive framework that supports
the `@Controller` programming model. It re-defines many of the Spring MVC contracts
such as `HandlerMapping` and `HandlerAdapter` to be asynchronous and
non-blocking and to operate on the reactive HTTP request and response. For this reason
[[web-reactive-server-annotation]]
==== Annotation-based programming model
The `@Controller` programming model supported by Spring Web Reactive re-defines many of
the Spring MVC contracts such as `HandlerMapping` and `HandlerAdapter` to be asynchronous
and non-blocking and to operate on the reactive HTTP request and response. For this reason
Spring MVC and Spring Web Reactive cannot share any code. However they do share
many of the same algorithms.
The end result is a programming model identical to today's Spring MVC but
with support for reactive types and executed in a reactive manner.
For example a controller method can declare a `@RequestBody` method argument
in any one of the following ways:
* `Account account` -- the account is deserialized without
blocking before the controller is invoked.
* `Mono<Account> account` -- the controller can use the `Mono`
to declare logic to be executed after the account is deserialized.
* `Single<Account> account` -- same as with `Mono` but using RxJava
https://github.com/bclozel/spring-boot-web-reactive#spring-boot-web-reactive-starter[Spring Boot Web Reactive starter]
available via http://start.spring.io
is the fastest way to get started. It does all that's necessary so you can start
available via http://start.spring.io is the fastest way to get started if you want to use
the annotation-based programming model. It does all that's necessary so you can start
writing `@Controller` classes. By default it runs on Tomcat but the dependencies can
be changed as usual with Spring Boot to switch to a different runtime.
There is no Spring Boot Starter available yet for the functional programming model, so for
this one use the manual bootstraping method described bellow.
[[web-reactive-getting-started-manual]]
=== Manual Bootstrapping
@ -159,7 +240,7 @@ be changed as usual with Spring Boot to switch to a different runtime.
@@ -159,7 +240,7 @@ be changed as usual with Spring Boot to switch to a different runtime.
This section outlines the steps to get up and running without Spring Boot.
For dependencies start with `spring-web-reactive` and `spring-context`.
Then add `jackson-databind` and `io.netty:netty-buffer:4.1.3.Final`
Then add `jackson-databind` and `io.netty:netty-buffer`
(temporarily see https://jira.spring.io/browse/SPR-14528[SPR-14528]) for JSON support.
Lastly add the dependencies for one of the supported runtimes:
@ -169,7 +250,7 @@ Lastly add the dependencies for one of the supported runtimes:
@@ -169,7 +250,7 @@ Lastly add the dependencies for one of the supported runtimes:
* RxNetty -- `io.reactivex:rxnetty-common` and `io.reactivex:rxnetty-http`
* Undertow -- `io.undertow:undertow-core`
For the bootstrap code start with:
For the **annotation-based programming model**, bootstrap code start with:
The above loads default Spring Web Reactive config (1), then creates a
`DispatcherHandler`, the main class driving request processing (2), and adapts
it to `HttpHandler`, the lowest level Spring abstraction for reactive HTTP request handling.
An `HttpHandler` can then be installed in each supported runtime:
For the **functional programming model**, bootstrap code start with:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
ApplicationContext context = new AnnotationConfigApplicationContext(); // (1)
context.registerBean(FooBean.class, () -> new FooBeanImpl()); // (2)
context.registerBean(BarBean.class); // (3)
HttpHandler handler = WebHttpHandlerBuilder
.webHandler(RouterFunctions.toHttpHandler(...))
.applicationContext(context)
.build(); // (4)
----
The above creates an `AnnotationConfigApplicationContext` instance (1) that can take advantage
of the new functional bean registration API (2) to register beans using a Java 8 `Supplier`
or just by specifying its class (3). The `HttpHandler` is created using `WebHttpHandlerBuilder` (4).
**Common to both** annotation and functional flavors, an `HttpHandler` can then be installed in each supported runtime:
[source,java,indent=0]
[subs="verbatim,quotes"]
@ -191,8 +290,10 @@ HttpServlet servlet = new ServletHttpHandlerAdapter(handler);
@@ -191,8 +290,10 @@ HttpServlet servlet = new ServletHttpHandlerAdapter(handler);
// Reactor Netty
ReactorHttpHandlerAdapter adapter = new ReactorHttpHandlerAdapter(handler);
HttpServer server = HttpServer.create(host, port);
server.startAndAwait(adapter);
HttpServer.create(host, port)
.newHandler(adapter)
.doOnNext(c -> System.out.println("Server listening on " + c.address())).block()
.onClose().block();
// RxNetty
RxNettyHttpHandlerAdapter adapter = new RxNettyHttpHandlerAdapter(handler);
@ -213,12 +314,17 @@ and it registers for you the `ServletHttpHandlerAdapter` shown above.
@@ -213,12 +314,17 @@ and it registers for you the `ServletHttpHandlerAdapter` shown above.
Only implement one method to point to your Spring Java configuration classes.
====
[[web-reactive-getting-started-examples]]
=== Examples
You will find code examples useful to build your own Spring Web Reactive application in these projects:
[[web-reactive-getting-started-M1]]
=== Extent of Support in 5.0 M1
For M1 the Spring Web Reactive module focuses on REST scenarios for both
client and server. Basic HTML rendering with Freemarker is also supported but
limited to rendering but not form submissions.
* https://github.com/bclozel/spring-boot-web-reactive[Spring Boot Web Reactive Starter]: sources of the reactive starter available at http://start.spring.io
* https://github.com/poutsma/web-function-sample[Functional programming model sample]
* https://github.com/sdeleuze/spring-reactive-playground[Spring Reactive Playground]: plaground for most Spring Web Reactive features
* https://github.com/reactor/projectreactor.io/tree/spring-functional[Reactor website]: the `spring-functional` branch is a Spring Web Reactive functional web application
* https://github.com/bclozel/spring-reactive-university[Spring Reactive University]: live-coded project from https://www.youtube.com/watch?v=Cj4foJzPF80[this Devoxx BE 2106 university talk]
* https://github.com/mix-it/mixit/[Mix-it 2017 website]: Kotlin + Reactive + Functional web and bean registration API application
* https://github.com/simonbasle/reactor-by-example[Reactor by example]: code snippets coming from this https://www.infoq.com/articles/reactor-by-example[InfoQ article]
* https://github.com/spring-projects/spring-framework/tree/master/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/annotation[Spring Web Reactive integration tests]: various features tested with Reactor https://projectreactor.io/docs/test/release/api/index.html?reactor/test/StepVerifier.html[`StepVerifier`]