I have a Spring Boot/Webflux application. I need an async REST endpoint that does:
- Generate random job id.
- Call one service via HTTP.
- Call another service via HTTP.
- Combine responses from the services and write the result into a file.
- Return the job id to the client.
The endpoint should be async. That's why a client shouldn't wait the result of steps: 2,3,4. The client should receive a job id instantly.
Right now I have following implementation:
@Override
public Mono<String> saveData() {
String jobId = UUID.randomUUID().toString();
Mono<ResponseFromService1> response1 = service1.getData();
Mono<ResponseFromService2> response2 = service2.getData();
return fileService.saveData(response1, response2)
.map(filePath -> log.info("File has been stored at {}", filePath))
.map(jobId);
service1 and service2 are implemented by using reactive WebClient. Implementation of fileService.saveData looks like:
public Mono<Path> saveDataInFile(Mono<ResponseFromService1> response1,Mono<ResponseFromService2> response2) {
return Mono.fromCallable(() ->
Mono.zip(response1, response2)
.map(tuple -> blockingIOsaveMethod(tuple.getT1(), tuple.getT2()))
).publishOn(Schedulers.elastic())
.flatMap(mono -> mono);
}
The problem is that this endpoint is not asynchronous. The client of the endpoint gets the job id after the file with data was saved. How should I update saveDataInFile and saveData to return the job id instantly?