From 5cf8b695cb50206204636e8602b3c68d3d46b7c0 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Mon, 25 Jul 2016 18:33:43 -0400 Subject: [PATCH] Add chapter on Spring Web Reactive support Issue: SPR-14497 --- src/asciidoc/images/web-reactive-overview.png | Bin 0 -> 48000 bytes src/asciidoc/web-reactive.adoc | 196 ++++++++++++++++++ src/asciidoc/web.adoc | 2 + 3 files changed, 198 insertions(+) create mode 100644 src/asciidoc/images/web-reactive-overview.png create mode 100644 src/asciidoc/web-reactive.adoc diff --git a/src/asciidoc/images/web-reactive-overview.png b/src/asciidoc/images/web-reactive-overview.png new file mode 100644 index 0000000000000000000000000000000000000000..65538cf8c419fc01df52aeb8b111671febc6f009 GIT binary patch literal 48000 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

MFqQ1J;KH_~%rn4W{R-ZaOsLC3CqM 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 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 +along with some basic implementations. + +The `spring-web` modules adds JSON and XML implementations for use in reactive +web applications and also provides support for SSE streaming and zero-copy +file transfer. + +The `spring-web-reactive` module defines many of the same contracts as +Spring MVC such as `HandlerMapping` and `HandlerAdapter` among others. +These reactive counterparts have asynchronous and non-blocking semantics and +operate on the reactive HTTP request and response abstractions. + +The end result is a programming model identical to today's Spring MVC but +supporting reactive types and executing on a reactive, non-blocking foundation. +For example a controller method can declare any of the following as a method argument: + +* `@RequestBody Account account` -- the account is deserialized without +blocking before the controller method is invoked. +* `@RequestBody Mono account` -- the controller can use the `Mono` +type to declare the logic execute when the account is deserialized. +* `@RequestBody Single account` -- same but with RxJava +* `@RequestBody Flux` accounts` -- streaming scenario. +* `@RequestBody Observable accounts` -- streaming with RxJava. + +The same principle also applies on the side of return value handling. + + +[[web-reactive-client]] +=== Reactive Web Client + +Spring Framework 5 adds a new reactive `WebClient` in addition to the existing `RestTemplate`. + +Much like on the server side each supported HTTP client is adapted to a set of shared, +reactive `ClientHttpRequest` and `ClientHttpResponse` abstractions that expose the request +and response body as `Flux` with full backpressure support on the read and +the write side. The `Encoder` and `Decoder` abstractions from `spring-core` also used on +the client side for serialization of a `Flux` of bytes to and from typed objects. + +Below is an example: + +[source,java,indent=0] +[subs="verbatim,quotes"] +---- +ClientHttpConnector httpConnector = new ReactorClientHttpConnector(); +WebClient webClient = new WebClient(httpConnector); + +Mono response = webClient + .perform(get("http://example.com/accounts/1").accept(APPLICATION_JSON)) + .extract(body(Account.class)); +---- + +The above example assumes the import of static methods from `ClientWebRequestBuilder` +and `ResponseExtractors`. The enable a fluent syntax similar to that of the MockMvc API +from Spring MVC Test. The same can also be done with RxJava. Simply replace with static +imports from `RxJava1ClientWebRequestBuilder` and `RxJava1ResponseExtractors`: + +[source,java,indent=0] +[subs="verbatim,quotes"] +---- +Single response = webClient + .perform(get("http://example.com/accounts/1").accept(APPLICATION_JSON)) + .extract(body(Account.class)); +---- + + +[[web-reactive-getting-started]] +== Getting Started + + +[[web-reactive-getting-started-boot]] +=== Spring Boot Starter + +The quickest way to get started is through the experimental Spring Boot Web Reactive +starter available on http://start.spring.io. It does all the work so you can simply start +writing `@Controller` classes. By default the starter runs with Tomcat but you can change +the dependencies and use one of the other supported HTTP runtimes. + + +[[web-reactive-getting-started-manual]] +=== Manual Bootstrapping + +It is also easy to get started by writing a few lines of code: + +[source,java,indent=0] +[subs="verbatim,quotes"] +---- +AnnotationConfigApplicationContext context; +context = new AnnotationConfigApplicationContext(); +context.register(WebReactiveConfiguration.class); // (1) +context.refresh(); + +DispatcherHandler handler = new DispatcherHandler(); // (2) +handler.setApplicationContext(context); +HttpHandler httpHandler = WebHttpHandlerBuilder.webHandler(handler).build(); + +HttpServer server = new TomcatHttpServer(); // (3) +server.setPort(8080); +server.setHandler(httpHandler); +server.afterPropertiesSet(); +server.start(); +---- + +The `WebReactiveConfiguration` at (1) is the Web Reactive Java config from the `spring-web-reactive` +and is similar in purpose to the MVC Java config from `spring-webmvc`. It provides the +the web framework configuration required to get started leaving you only to +declare your own `@Controller' beans. + +The `DispatcherHandler` at (2) is the equivalent of the `DispatcherServlet` in Spring MVC. + +The `HttpServer` at (3) is an abstraction from the +https://github.com/spring-projects/spring-framework/tree/master/spring-web/src/test/java/org/springframework/http/server/reactive/bootstrap[test sources] +of the `spring-web-reactive` module that's used for the framework's own integration tests. +It comes with basic implementations of all supported runtimes. + + +[[web-reactive-getting-started-M1]] +=== Extent of M1 Support + +For M1 the Spring Web Reactive module focuses on support for REST scenarios both +client and server-side. Basic HTML rendering with Freemarker is also supported but +limited to rendering, i.e. there is no support form submissions yet. + +On the client side for M1 the Reactor Netty HTTP client is supported. diff --git a/src/asciidoc/web.adoc b/src/asciidoc/web.adoc index 380934cc41..8a7a56bda3 100644 --- a/src/asciidoc/web.adoc +++ b/src/asciidoc/web.adoc @@ -29,3 +29,5 @@ include::web-cors.adoc[leveloffset=+1] include::web-integration.adoc[leveloffset=+1] include::web-websocket.adoc[leveloffset=+1] + +include::web-reactive.adoc[leveloffset=+1]