I have a requirement to write Spring Webflux endpoint ( Router function ) to send out mail to list of the mail recipients. UI will select the list of mail recipients and sends out the list to the API that I will be writing. Im looking to imlement the endpoint in such a way as soon I receive the request, I should send out the response to the UI saying the Emails are being sent. After sending the response, I should continue the mail sending work asynchronously. I can't use @async annotation like we use in Spring MVC as it an anti pattern in the reactive world.
Since Im using spring webflux to develop API, how can i send the repsonse.
I have a below strucuture in my code.
Router.java
@Bean
public RouterFunction<ServerResponse> sendEmail() {
return route(POST("/email").and(accept(APPLICATION_JSON)), handler::sendEmail);
}
Handler.java
@Autowired
EmailService emailService;
public Mono<ServerResponse> sendEmail(ServerRequest request) {
Mono<PojoA> pojoAMono = request.bodyToMono(PojoA.class);
return pojoAMono.flatMap(pojoA -> {
return emailService.sendEmail(pojoA).flatMap(mailSent -> {
return ServerResponse
.status(HttpStatus.OK)
.contentType(MediaType.APPLICATION_JSON)
.body("Mails are being sent", String.class));
});
});
}
You should build the response and then process the data (send email).
Something like this:
@Bean
public RouterFunction<ServerResponse> sendEmail() {
return route(POST("/test").and(accept(APPLICATION_JSON)), this::someMethod);
}
Mono<ServerResponse> someMethod(ServerRequest serverRequest) {
return ServerResponse.ok().build()
.doOnNext(r -> Mono.just("data") //doing some process like send email
.delayElement(Duration.ofSeconds(2))
.subscribeOn(Schedulers.parallel())
.log()
.subscribe());
}
For testing purpose, I put a delay to you see the data processing after response sent.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With