How to Return Flux as response when using Spring Reactor and Spring Boot? - spring-boot

I am trying to use Spring Reactor with my Spring Boot application.
I am using Project Reactor 3.0.7.RELEASE and Spring Boot 1.5.3.RELEASE.
I have a method in my Service class which returns Flux.
I want to return the value to controller in web layer. But, I do not see the values returns in the json response.
When I invoke http://localhost:8080 from browser, I get response as,
{"prefetch":-1}
I am not sure if I should I do some conversion from Flux to String before returning the response.
I have my code shared in ,
https://github.com/bsridhar123/spring-reactor-demo/blob/master/src/main/java/com/demo/reactor/ReactiveApp.java
Can you please help me on the correct approach for it.

Full reactive support using Reactor is only implemented in Spring 5 (currently in RC phase) and Spring Boot 2 (currently in Milestone phase).
You can use Reactor independently of Spring, but that doesn't make the framework reactive and asynchronous so you lose some benefit. You cannot simply return a Flux as the framework doesn't yet understand this type.
However, I believe it can still be useful in the service layer, if you have to orchestrate a lot of service calls.
What you can do in this case is to use Flux and Mono throughout your service layer and convert those to Spring 4's DeferredResult. Something like:
DeferredResult<ResponseEntity<String>> result = new DeferredResult<>();
service.getSomeStringMono()
.map(n -> ResponseEntity.ok(n))
.defaultIfEmpty(ResponseEntity.notFound().build()
.subscribe(re -> result.setResult(re),
error -> result.setErrorResult(error));
return result;

Related

Can I use Spring's WebClient for the synchronous app, and what are the alternatives?

I am creating a Spring Boot MVC application, with Tomcat and JDBC. My app will be an API client, I've learned that I'll need RestTemplate class for API requests. But since Spring 5, RestTemplate is in maintenance mode and will be deprecated in the future.
The alternative is a WebClient class, which is powerful and useful for testing also. But it supports a reactive WebFlux stack.
For example, when I watched this tutorial on how to make tests with WebClient I was very confused:
https://www.youtube.com/watch?v=kGK9Hf8cnBw
I must use these Mono and Flux types?
My first question is, can I use WebClient to make a classic servlet-based app (with Tomcat, and JDBC/JPA like I used to)?
If not, what is an alternative to WebClient and RestTemplate?
WebClient can be used in synchronous style by blocking at the end for the result like this:
Person project = client.get().uri("/project/{id}", i).retrieve()
.bodyToMono(Project.class)
.block();
List<Person> projects = client.get().uri("/projects").retrieve()
.bodyToFlux(Project.class)
.collectList()
.block();
Here we use block() to block the stream and get the data out of it. Note that this shouldn’t be used in a reactive environment.
This is late but someone might benefit from this.. You can use open feign.. Check it out

How to make Spring Data REST endpoints asynchronous?

Does anyone know how to make Spring Data REST endpoints asynchronous?
I saw that we can add the annotation #Async with CompletableFuture<?> as returned object on the service methods.
But doing this, makes the use of the interface RepositoryRestResource pointless as we need to implement both the service and controller layers manually...
Or am I missing something here?
Currently Spring Data REST supports blocking I/O only. See this Jira Issue of Spring Data REST support for Spring WebFlux.
Spring MVC has an integration with Servlet 3.0 async request processing.
Although Spring MVC has async support, for non-blocking I/O, Spring WebFlux is recommended, because Spring WebFlux is async by design. See Spring Web MVC Async Request Compared to WebFlux

Spring Reactor Web Client use case. replacing RestTemplate with WebClient

I am working on a microservice project where my individual spring boot microservices would be calling themselves and mainly to 3rd party API's to fetch and save data.
Since I am with legacy Spring boot application I can't think of replacing it with Reactor based Microservices.
But I am thinking of replacing My RestTemplate (using for communication with Other MS's and 3rd Party App) with new Spring Reactor Webclient to get some advantages of Async calls.
Is My use case a right candidate for Using Spring reactor WebClient?
Yes, composition of microservice and REST calls is a good use case for WebClient.
Plus Spring Boot 2 will let you combine the Spring MVC starter with the WebFlux starter and interpret that as "you want to run on the servlet stack, but might want to use WebClient sporadically".

Integrating spring Websession with spring reactive web flux

There is a new implementation of http session for spring new reactive web flux api located here.
I would like to integrate the latest spring web session in the new spring reactive web flux. I can't seem to get it, I tried injecting it as a bean, but it does not work. I would like to inject it like I usually do with HttpSession
something like
#Autowired
Websession webSession;
Because Spring WebFlux is a reactive web framework, you can't expect the Web Session to be injected as a bean (even in the request scope). In the Servlet world, each request/response is processed in a single thread, which enables those approaches (i.e. the "request" scope). With WebFlux, a given request can be processed by multiple threads.
The WebSession instance associated with the current request/response is actually attached to the ServerWebExchange (see getSession). Because of the nature of the reactive programming model, you're very likely to access that session within a Reactor operator - so you can't expect to inject this instance somewhere else in your application.

Restful Service with Spring Integration

I want to integration a restful interface with Spring Integration. I'm fairly new to Spring Integration and don't really know where to start. The goal is that the restful interface is polled regularly and then a Spring Batch job is automatically started with the new data. Is there somewhere a good example of how to do that? Where is a good point to start? I would like to implement this with Spring DSL.
IntegrationFlows.from(// MessageSource to generate request //
, e -> e.poller(...))
.handle(Http(outboundGateway(...))
.transform(// to JobLaunchRequest //)
.handle(// JobLaunchingRequestHandler //)
.handle(// JobExecutionResult //)
.get();
Refer to the Spring Integration Documentation for information about configuring the HTTP gateway and concepts of transformers, message handlers, and the spring-batch-integration project (part of spring-batch) for JobLaunchingRequestHandler etc.

Resources