The reactive web and MVC frameworks

As we might remember, the key feature of the Spring Web MVC module is its annotation-based programming model. The central challenge, therefore, is providing the same concept for the reactive web stack. If we look at the current Spring Web MVC module, we can see that, in general, the module is designed properly. Instead of building a new reactive MVC infrastructure, we may reuse the existing one and replace synchronous communication with reactive types such as Flux, Mono, and Publisher. For example, two central interfaces for mapping requests and binding contextual information (such as headers, query parameters, attributes, and sessions) to the handler that have been found are HandlerMapping and HandlerAdapter. In general, we can keep the same chain of HandlerMapping and HandlerAdapter as in Spring Web MVC, but replace the eager imperative with the reactive interaction using Reactor's types:

interface HandlerMapping {                                         // (1)
/* HandlerExecutionChain getHandler(HttpServletRequest request) */ // (1.1)
Mono<Object> getHandler(ServerWebExchange exchange); // (1.2)
} //

interface HandlerAdapter { // (2)
boolean supports(Object handler); //
//
/* ModelAndView handle( // (2.1)
HttpServletRequest request, HttpServletResponse response, //
Object handler //
) */ //
Mono<HandlerResult> handle( // (2.2)
ServerWebExchange exchange, //
Object handler //
); //
} //

The preceding code is explained in the following numbered list:

  1. This is the declaration of the reactive HandlerMapping interface. Here, to highlight the difference between the old Web MVC implementation and the improved one, the code contains the declarations of both methods. The old implementation, at point (1.1), is commented with /* ... */ and uses the italic font style, while the new interface, at point (1.2)is highlighted in bold. As we can see, in general, the methods are very similar. The difference is that the last one returns the Mono type, therefore enabling reactive behaviors.
  2. This is the reactive HandlerAdapter interface version. As we can see here, the reactive version of the handle method is a bit more succinct since the ServerWebExchange class combines the request and response instances at the same time. At point (2.2), the method returns Mono of the HandlerResult instead of ModelAndView (which is at 2.1). As we may remember, ModelAndView is responsible for providing information such as a status code, Model, and View. The HandlerResult class contains the same information, apart from the status code. HandlerResult is better, since it provides the result of the direct execution, so it is easier for DispatcherHandler to find a handler. In Web MVC, View is responsible for rendering templates as well as objects. It also renders results, so its purpose in Web MVC can be a bit unclear. Unfortunately, such multiple responsibilities cannot be easily adapted to asynchronous result processing. In such cases, when the result is a plain Java object, the View lookup is done in HandlerAdapter, which is not a direct responsibility of that class. Because of this, it is better to keep the responsibility clear, so the change implemented in the preceding code is an improvement.

Following these steps will give us a reactive interaction model without breaking the whole execution hierarchy, thereby preserving the existing design and potentially reusing existing code with minimal changes. 

Finally, by gathering all of the steps that we have taken so far toward achieving a reactive web stack and correcting the processing flow of a request, taking into account the real implementation, we will come up with the following design:

Diagram 6.2. The redesigned reactive web and MVC stack

The preceding diagram may be explained as follows:

  1. This is the incoming request, which is handled by the underlying Server Engine. As we can see, the list of server engines is not limited to Servlet API-based servers and now includes engines such as Netty and Undertow. Here, each server engine has its own reactive adapter, which maps the internal representations of HTTP requests and HTTP responses to ServerHttpRequest and ServerHttpResponse.
  2. This is the HttpHandler stage, which composes the given ServerHttpRequest, the ServerHttpResponse, the user's Session, and related information into a ServerWebExchage instance.
  3. At this point, we have the WebFilterChain stage, which composes the defined WebFilter into the chain. Then, WebFilterChain is responsible for executing the WebFilter#filter method of each WebFilter instance in this chain, in order to filter the incoming ServerWebExchange.
  4. If all filter conditions are met, WebFilterChain calls the WebHandler instance.
  5. The next step is to look up instances of HandlerMapping and invoke the first suitable one. In this example, we depicted a few HandlerMapping instances, such as RouterFunctionMapping, the well-known RequestMappingHandlerMapping, and the HandlerMapping resource. The new HandlerMapping instance here is RouterFunctionMapping, which is introduced in the WebFlux module and goes beyond purely functional request handling. We will not go into details of that feature here; we will cover this in the following section.
  6. This is the RequestMappingHandlerAdapter stage, which has the same functionality as it did previously, but now uses Reactive Streams in order to build a reactive interaction flow.

The preceding diagram depicts only a simplified view of the underlying interaction flow in a WebFlux module. It should be noted that in the WebFlux module, the default server engine is Netty. The Netty server is an appropriate default since it is widely used in the reactive space. Also, that server engine provides both client and server asynchronous non-blocking interaction. This means that it's better for the reactive programming paradigm offered by Spring WebFlux. Despite the fact that Netty is a good default server engine, with WebFlux, we have the flexibility to choose our server engine, meaning we can easily switch between various modern server engines such as Undertow, Tomcat, Jetty, or any other Servlet API-based server. As we can see, the WebFlux module mirrors the architecture of the Spring Web MVC module, so it makes it easy to understand for those with experience with the old web framework. Also, the Spring Web Flux module has a lot of hidden gems, which will be covered in the following sections.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.202.61