The Annotation-based programming model

You can use the same annotations that you have used in Chapter 10, Implementing MVC pattern in a Web Application with Spring. Annotations such as @Controller and @RestController of Spring MVC are also supported on the reactive side. There is no difference till now between the traditional Spring MVC and Spring web with reactive module. The actual difference starts after the @Controller annotation configuration declaration, that is, when we go to the internal working of the Spring MVC, starting with HandlerMapping and HandlerAdapter.

The main difference between the traditional Spring MVC and Spring web reactive comes into play in the request-handling mechanism. Spring MVC without reactive handles the requests using the blocking HttpServletRequest and the HttpServletResponse interfaces of the Servlet API, but the Spring web reactive framework is non-blocking, and operates on the reactive ServerHttpRequest and ServerHttpResponse rather than on HttpServletRequest and HttpServletResponse.

Let's see the following example with a reactive controller:

    package com.packt.patterninspring.chapter11.
reactivewebapp.controller; import org.reactivestreams.Publisher; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import com.packt.patterninspring.chapter11.
reactivewebapp.model.Account; import com.packt.patterninspring.chapter11.
reactivewebapp.repository.AccountRepository; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @RestController public class AccountController { @Autowired private AccountRepository repository; @GetMapping(value = "/account") public Flux<Account> findAll() { return repository.findAll().map(a -> new
Account(a.getId(), a.getName(),
a.getBalance(), a.getBranch())); } @GetMapping(value = "/account/{id}") public Mono<Account> findById(@PathVariable("id") Long id) { return repository.findById(id) .map(a -> new Account(a.getId(), a.getName(), a.getBalance(),
a.getBranch())); } @PostMapping("/account") public Mono<Account> create(@RequestBody
Publisher<Account> accountStream) { return repository .save(Mono.from(accountStream) .map(a -> new Account(a.getId(), a.getName(), a.getBalance(),
a.getBranch()))) .map(a -> new Account(a.getId(), a.getName(), a.getBalance(),
a.getBranch())); } }

As you can see in the preceding Controller code of AccountController.java, I have used the same Spring MVC annotations such as @RestController to declare a controller class, and @GetMapping and @PostMapping are used to create the request handler methods for the GET and POST request methods respectively.

Let's focus on the return types of the handler methods. These methods return values as Mono and Flux types. These are types of the reactive steams provided by the reactor framework. Also, the handler method takes the request body using the Publisher type.

Reactor is a Java Framework from the Pivotal open-source team. It builds directly on Reactive Streams, so there is no need for a bridge. The Reactor IO project provides wrappers around low-level network runtimes like Netty and Aeron. Reactor is a "4th Generation" library according to David Karnok's Generations of Reactive classification.

Let's look at the same controller class using the functional programming model to handle requests.

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

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