I have an API endpoint that's using Spring Boot. What this endpoint does is it calls two other API endpoints and processes their response.
The first half of the process calls one API endpoint, get the response and return this response with a 202 Accepted to the surface.
After the 202 has been returned, the background is undergoing the second half of the process. Which is taking the response from the first API calls and further processing it.
I tried with Executor
or CompletableFuture
but both of them stopped after its return 202 and will not run the second half or they wait until the second half to complete only return the 202.
Is this possible to achieve or am I looking into wrong design?
Here is some sample code:
@PostMapping("/user")
public ResponseEntity<?> processUser(@Valid @RequestBody UserRequestDto request,
@RequestHeader("Authorization") String token) throws Exception {
CompletableFuture<UserResponseDto> response = CompletableFuture.supplyAsync(() ->
userService.processUser(request, token));
userService.processUserSecond(response, token);
return new ResponseEntity<>(response, HttpStatus.ACCEPTED);
}
CodePudding user response:
To make it clear: The REST endpoint consists of two calls - processUser
and processUserSecond
. You want to get the result of the processUser
, return its result and fire the processUserSecond
asynchronously without waiting for its result.
Remember, in that case, the first call must be synchronous since you wait for its result to be returned. The latter can be asynchronous.
@PostMapping("/user")
public ResponseEntity<?> processUser(@Valid @RequestBody UserRequestDto request,
@RequestHeader("Authorization") String token)
{
// synchronous, waiting for the response to be returned
UserResponseDto response = userService.processUser(request, token);
// asynchronous, fired without waiting for the response
CompletableFuture.runAsync(() -> userService.processUserSecond(response, token));
// return the result of the first (an only) synchronous call
return new ResponseEntity<>(response, HttpStatus.ACCEPTED);
}