Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@Async API endpoint Spring Webflux

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));
       });
    });
    
}
like image 212
Ashok B Avatar asked Aug 31 '26 09:08

Ashok B


1 Answers

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.

like image 176
Raul Lopes Avatar answered Sep 02 '26 02:09

Raul Lopes



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!